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
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
32 #include "wine/debug.h"
34 #include "d3d_private.h"
35 #include "mesa_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
39 /* Structure to store the 'semi transformed' vertices */
67 static void _dump_d3dstatus(LPD3DSTATUS lpStatus
) {
71 static void _dump_executedata(LPD3DEXECUTEDATA lpData
) {
72 DPRINTF("dwSize : %ld\n", lpData
->dwSize
);
73 DPRINTF("Vertex Offset : %ld Count : %ld\n", lpData
->dwVertexOffset
, lpData
->dwVertexCount
);
74 DPRINTF("Instruction Offset : %ld Length : %ld\n", lpData
->dwInstructionOffset
, lpData
->dwInstructionLength
);
75 DPRINTF("HVertex Offset : %ld\n", lpData
->dwHVertexOffset
);
76 _dump_d3dstatus(&(lpData
->dsStatus
));
79 static void _dump_D3DEXECUTEBUFFERDESC(LPD3DEXECUTEBUFFERDESC lpDesc
) {
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 < 1e-8) \
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(IDirect3DExecuteBufferImpl
*This
,
187 IDirect3DDeviceImpl
*lpDevice
,
188 IDirect3DViewportImpl
*lpViewport
)
190 IDirect3DDeviceGLImpl
* lpDeviceGL
= (IDirect3DDeviceGLImpl
*) lpDevice
;
191 /* DWORD bs = This->desc.dwBufferSize; */
192 DWORD vs
= This
->data
.dwVertexOffset
;
193 /* DWORD vc = This->data.dwVertexCount; */
194 DWORD is
= This
->data
.dwInstructionOffset
;
195 /* DWORD il = This->data.dwInstructionLength; */
197 void *instr
= This
->desc
.lpData
+ is
;
199 /* Should check if the viewport was added or not to the device */
201 /* Activate the viewport */
202 lpViewport
->active_device
= lpDevice
;
203 lpViewport
->activate(lpViewport
);
205 TRACE("ExecuteData : \n");
207 _dump_executedata(&(This
->data
));
212 LPD3DINSTRUCTION current
= (LPD3DINSTRUCTION
) instr
;
216 count
= current
->wCount
;
217 size
= current
->bSize
;
218 instr
+= sizeof(D3DINSTRUCTION
);
220 switch (current
->bOpcode
) {
222 WARN("POINT-s (%d)\n", count
);
223 instr
+= count
* size
;
227 WARN("LINE-s (%d)\n", count
);
228 instr
+= count
* size
;
231 case D3DOP_TRIANGLE
: {
233 OGL_Vertex
*vx
= (OGL_Vertex
*) This
->vertex_data
;
234 OGL_LVertex
*l_vx
= (OGL_LVertex
*) This
->vertex_data
;
235 D3DTLVERTEX
*tl_vx
= (D3DTLVERTEX
*) This
->vertex_data
;
236 TRACE("TRIANGLE (%d)\n", count
);
238 switch (This
->vertex_type
) {
240 /* This time, there is lighting */
241 glEnable(GL_LIGHTING
);
243 if (TRACE_ON(ddraw
)) {
244 TRACE(" Projection Matrix : (%p)\n", lpDevice
->proj_mat
);
245 dump_D3DMATRIX(lpDevice
->proj_mat
);
246 TRACE(" View Matrix : (%p)\n", lpDevice
->view_mat
);
247 dump_D3DMATRIX(lpDevice
->view_mat
);
250 /* Using the identity matrix as the world matrix as the world transformation was
252 lpDevice
->set_matrices(lpDevice
, VIEWMAT_CHANGED
|WORLDMAT_CHANGED
|PROJMAT_CHANGED
,
253 (D3DMATRIX
*) id_mat
, lpDevice
->view_mat
, lpDevice
->proj_mat
);
258 glDisable(GL_LIGHTING
);
260 if (TRACE_ON(ddraw
)) {
261 TRACE(" Projection Matrix : (%p)\n", lpDevice
->proj_mat
);
262 dump_D3DMATRIX(lpDevice
->proj_mat
);
263 TRACE(" View Matrix : (%p)\n", lpDevice
->view_mat
);
264 dump_D3DMATRIX(lpDevice
->view_mat
);
267 /* Using the identity matrix as the world matrix as the world transformation was
269 lpDevice
->set_matrices(lpDevice
, VIEWMAT_CHANGED
|WORLDMAT_CHANGED
|PROJMAT_CHANGED
,
270 (D3DMATRIX
*) id_mat
, lpDevice
->view_mat
, lpDevice
->proj_mat
);
273 case D3DVT_TLVERTEX
: {
274 /* First, disable lighting and fogging */
275 glDisable(GL_LIGHTING
);
278 d3ddevice_set_ortho(lpDevice
);
282 ERR("Unhandled vertex type !\n");
286 switch (This
->vertex_type
) {
288 TRIANGLE_LOOP(DO_VERTEX
);
292 TRIANGLE_LOOP(DO_LVERTEX
);
296 TRIANGLE_LOOP(DO_TLVERTEX
);
300 ERR("Unhandled vertex type !\n");
304 case D3DOP_MATRIXLOAD
:
305 WARN("MATRIXLOAD-s (%d)\n", count
);
306 instr
+= count
* size
;
309 case D3DOP_MATRIXMULTIPLY
: {
311 TRACE("MATRIXMULTIPLY (%d)\n", count
);
313 for (i
= 0; i
< count
; i
++) {
314 LPD3DMATRIXMULTIPLY ci
= (LPD3DMATRIXMULTIPLY
) instr
;
315 LPD3DMATRIX a
= (LPD3DMATRIX
) ci
->hDestMatrix
;
316 LPD3DMATRIX b
= (LPD3DMATRIX
) ci
->hSrcMatrix1
;
317 LPD3DMATRIX c
= (LPD3DMATRIX
) ci
->hSrcMatrix2
;
319 TRACE(" Dest : %08lx Src1 : %08lx Src2 : %08lx\n",
320 ci
->hDestMatrix
, ci
->hSrcMatrix1
, ci
->hSrcMatrix2
);
322 /* Do the multiplication..
323 As I am VERY lazy, I let OpenGL do the multiplication for me */
324 glMatrixMode(GL_PROJECTION
);
325 /* Save the current matrix */
327 /* Load Matrix one and do the multiplication */
328 glLoadMatrixf((float *) c
);
329 glMultMatrixf((float *) b
);
330 glGetFloatv(GL_PROJECTION_MATRIX
, (float *) a
);
331 /* Restore the current matrix */
338 case D3DOP_STATETRANSFORM
: {
340 TRACE("STATETRANSFORM (%d)\n", count
);
342 for (i
= 0; i
< count
; i
++) {
343 LPD3DSTATE ci
= (LPD3DSTATE
) instr
;
345 /* Handle the state transform */
346 switch (ci
->u1
.dtstTransformStateType
) {
347 case D3DTRANSFORMSTATE_WORLD
: {
348 TRACE(" WORLD (%p)\n", (D3DMATRIX
*) ci
->u2
.dwArg
[0]);
349 lpDevice
->world_mat
= (D3DMATRIX
*) ci
->u2
.dwArg
[0];
352 case D3DTRANSFORMSTATE_VIEW
: {
353 TRACE(" VIEW (%p)\n", (D3DMATRIX
*) ci
->u2
.dwArg
[0]);
354 lpDevice
->view_mat
= (D3DMATRIX
*) ci
->u2
.dwArg
[0];
357 case D3DTRANSFORMSTATE_PROJECTION
: {
358 TRACE(" PROJECTION (%p)\n", (D3DMATRIX
*) ci
->u2
.dwArg
[0]);
359 lpDevice
->proj_mat
= (D3DMATRIX
*) ci
->u2
.dwArg
[0];
363 ERR(" Unhandled state transformation !! (%d)\n", (int) ci
->u1
.dtstTransformStateType
);
371 case D3DOP_STATELIGHT
: {
373 TRACE("STATELIGHT (%d)\n", count
);
375 for (i
= 0; i
< count
; i
++) {
376 LPD3DSTATE ci
= (LPD3DSTATE
) instr
;
378 /* Handle the state transform */
379 switch (ci
->u1
.dlstLightStateType
) {
380 case D3DLIGHTSTATE_MATERIAL
: {
381 IDirect3DMaterialImpl
* mat
= (IDirect3DMaterialImpl
*) ci
->u2
.dwArg
[0];
382 TRACE(" MATERIAL\n");
387 TRACE(" bad Material Handle\n");
391 case D3DLIGHTSTATE_AMBIENT
: {
393 DWORD dwLightState
= ci
->u2
.dwArg
[0];
396 light
[0] = ((dwLightState
>> 16) & 0xFF) / 255.0;
397 light
[1] = ((dwLightState
>> 8) & 0xFF) / 255.0;
398 light
[2] = ((dwLightState
>> 0) & 0xFF) / 255.0;
400 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, (float *) light
);
402 TRACE(" R:%02lx G:%02lx B:%02lx A:%02lx\n",
403 ((dwLightState
>> 16) & 0xFF),
404 ((dwLightState
>> 8) & 0xFF),
405 ((dwLightState
>> 0) & 0xFF),
406 ((dwLightState
>> 24) & 0xFF));
409 case D3DLIGHTSTATE_COLORMODEL
: {
410 WARN(" COLORMODEL\n");
413 case D3DLIGHTSTATE_FOGMODE
: {
417 case D3DLIGHTSTATE_FOGSTART
: {
421 case D3DLIGHTSTATE_FOGEND
: {
425 case D3DLIGHTSTATE_FOGDENSITY
: {
426 WARN(" FOGDENSITY\n");
430 ERR(" Unhandled light state !! (%d)\n", (int) ci
->u1
.dlstLightStateType
);
437 case D3DOP_STATERENDER
: {
439 TRACE("STATERENDER (%d)\n", count
);
441 for (i
= 0; i
< count
; i
++) {
442 LPD3DSTATE ci
= (LPD3DSTATE
) instr
;
444 /* Handle the state transform */
445 set_render_state(lpDeviceGL
, ci
->u1
.drstRenderStateType
, ci
->u2
.dwArg
[0]);
451 case D3DOP_PROCESSVERTICES
: {
453 TRACE("PROCESSVERTICES (%d)\n", count
);
455 for (i
= 0; i
< count
; i
++) {
456 LPD3DPROCESSVERTICES ci
= (LPD3DPROCESSVERTICES
) instr
;
458 TRACE(" Start : %d Dest : %d Count : %ld\n",
459 ci
->wStart
, ci
->wDest
, ci
->dwCount
);
461 if (TRACE_ON(ddraw
)) {
462 if (ci
->dwFlags
& D3DPROCESSVERTICES_COPY
)
464 if (ci
->dwFlags
& D3DPROCESSVERTICES_NOCOLOR
)
466 if (ci
->dwFlags
== D3DPROCESSVERTICES_OPMASK
)
468 if (ci
->dwFlags
& D3DPROCESSVERTICES_TRANSFORM
)
469 DPRINTF("TRANSFORM ");
470 if (ci
->dwFlags
== D3DPROCESSVERTICES_TRANSFORMLIGHT
)
471 DPRINTF("TRANSFORMLIGHT ");
472 if (ci
->dwFlags
& D3DPROCESSVERTICES_UPDATEEXTENTS
)
473 DPRINTF("UPDATEEXTENTS ");
477 /* This is where doing Direct3D on top on OpenGL is quite difficult.
478 This method transforms a set of vertices using the CURRENT state
479 (lighting, projection, ...) but does not rasterize them.
480 They will only be put on screen later (with the POINT / LINE and
481 TRIANGLE op-codes). The problem is that you can have a triangle
482 with each point having been transformed using another state...
484 In this implementation, I will emulate only ONE thing : each
485 vertex can have its own "WORLD" transformation (this is used in the
486 TWIST.EXE demo of the 5.2 SDK). I suppose that all vertices of the
487 execute buffer use the same state.
489 If I find applications that change other states, I will try to do a
490 more 'fine-tuned' state emulation (but I may become quite tricky if
491 it changes a light position in the middle of a triangle).
493 In this case, a 'direct' approach (i.e. without using OpenGL, but
494 writing our own 3D rasterizer) would be easier. */
496 /* The current method (with the hypothesis that only the WORLD matrix
497 will change between two points) is like this :
498 - I transform 'manually' all the vertices with the current WORLD
499 matrix and store them in the vertex buffer
500 - during the rasterization phase, the WORLD matrix will be set to
501 the Identity matrix */
503 /* Enough for the moment */
504 if (ci
->dwFlags
== D3DPROCESSVERTICES_TRANSFORMLIGHT
) {
506 D3DVERTEX
*src
= ((LPD3DVERTEX
) (This
->desc
.lpData
+ vs
)) + ci
->wStart
;
507 OGL_Vertex
*dst
= ((OGL_Vertex
*) (This
->vertex_data
)) + ci
->wDest
;
508 D3DMATRIX
*mat
= lpDevice
->world_mat
;
510 TRACE(" World Matrix : (%p)\n", mat
);
513 This
->vertex_type
= D3DVT_VERTEX
;
515 for (nb
= 0; nb
< ci
->dwCount
; nb
++) {
516 /* For the moment, no normal transformation... */
517 dst
->nx
= (src
->u4
.nx
* mat
->_11
) + (src
->u5
.ny
* mat
->_21
) + (src
->u6
.nz
* mat
->_31
);
518 dst
->ny
= (src
->u4
.nx
* mat
->_12
) + (src
->u5
.ny
* mat
->_22
) + (src
->u6
.nz
* mat
->_32
);
519 dst
->nz
= (src
->u4
.nx
* mat
->_13
) + (src
->u5
.ny
* mat
->_23
) + (src
->u6
.nz
* mat
->_33
);
524 /* Now, the matrix multiplication */
525 dst
->x
= (src
->u1
.x
* mat
->_11
) + (src
->u2
.y
* mat
->_21
) + (src
->u3
.z
* mat
->_31
) + (1.0 * mat
->_41
);
526 dst
->y
= (src
->u1
.x
* mat
->_12
) + (src
->u2
.y
* mat
->_22
) + (src
->u3
.z
* mat
->_32
) + (1.0 * mat
->_42
);
527 dst
->z
= (src
->u1
.x
* mat
->_13
) + (src
->u2
.y
* mat
->_23
) + (src
->u3
.z
* mat
->_33
) + (1.0 * mat
->_43
);
528 dst
->w
= (src
->u1
.x
* mat
->_14
) + (src
->u2
.y
* mat
->_24
) + (src
->u3
.z
* mat
->_34
) + (1.0 * mat
->_44
);
533 } else if (ci
->dwFlags
== D3DPROCESSVERTICES_TRANSFORM
) {
535 D3DLVERTEX
*src
= ((LPD3DLVERTEX
) (This
->desc
.lpData
+ vs
)) + ci
->wStart
;
536 OGL_LVertex
*dst
= ((OGL_LVertex
*) (This
->vertex_data
)) + ci
->wDest
;
537 D3DMATRIX
*mat
= lpDevice
->world_mat
;
539 TRACE(" World Matrix : (%p)\n", mat
);
542 This
->vertex_type
= D3DVT_LVERTEX
;
544 for (nb
= 0; nb
< ci
->dwCount
; nb
++) {
545 dst
->c
= src
->u4
.color
;
546 dst
->sc
= src
->u5
.specular
;
550 /* Now, the matrix multiplication */
551 dst
->x
= (src
->u1
.x
* mat
->_11
) + (src
->u2
.y
* mat
->_21
) + (src
->u3
.z
* mat
->_31
) + (1.0 * mat
->_41
);
552 dst
->y
= (src
->u1
.x
* mat
->_12
) + (src
->u2
.y
* mat
->_22
) + (src
->u3
.z
* mat
->_32
) + (1.0 * mat
->_42
);
553 dst
->z
= (src
->u1
.x
* mat
->_13
) + (src
->u2
.y
* mat
->_23
) + (src
->u3
.z
* mat
->_33
) + (1.0 * mat
->_43
);
554 dst
->w
= (src
->u1
.x
* mat
->_14
) + (src
->u2
.y
* mat
->_24
) + (src
->u3
.z
* mat
->_34
) + (1.0 * mat
->_44
);
559 } else if (ci
->dwFlags
== D3DPROCESSVERTICES_COPY
) {
560 D3DTLVERTEX
*src
= ((LPD3DTLVERTEX
) (This
->desc
.lpData
+ vs
)) + ci
->wStart
;
561 D3DTLVERTEX
*dst
= ((LPD3DTLVERTEX
) (This
->vertex_data
)) + ci
->wDest
;
563 This
->vertex_type
= D3DVT_TLVERTEX
;
565 memcpy(dst
, src
, ci
->dwCount
* sizeof(D3DTLVERTEX
));
567 ERR("Unhandled vertex processing !\n");
574 case D3DOP_TEXTURELOAD
: {
575 WARN("TEXTURELOAD-s (%d)\n", count
);
577 instr
+= count
* size
;
581 TRACE("EXIT (%d)\n", count
);
582 /* We did this instruction */
588 case D3DOP_BRANCHFORWARD
: {
590 TRACE("BRANCHFORWARD (%d)\n", count
);
592 for (i
= 0; i
< count
; i
++) {
593 LPD3DBRANCH ci
= (LPD3DBRANCH
) instr
;
595 if ((This
->data
.dsStatus
.dwStatus
& ci
->dwMask
) == ci
->dwValue
) {
597 TRACE(" Should branch to %ld\n", ci
->dwOffset
);
601 TRACE(" Should branch to %ld\n", ci
->dwOffset
);
610 WARN("SPAN-s (%d)\n", count
);
612 instr
+= count
* size
;
615 case D3DOP_SETSTATUS
: {
617 TRACE("SETSTATUS (%d)\n", count
);
619 for (i
= 0; i
< count
; i
++) {
620 LPD3DSTATUS ci
= (LPD3DSTATUS
) instr
;
622 This
->data
.dsStatus
= *ci
;
629 ERR("Unhandled OpCode !!!\n");
630 /* Try to save ... */
631 instr
+= count
* size
;
641 Main_IDirect3DExecuteBufferImpl_1_QueryInterface(LPDIRECT3DEXECUTEBUFFER iface
,
645 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
646 TRACE("(%p/%p)->(%s,%p)\n", This
, iface
, debugstr_guid(riid
), obp
);
650 if ( IsEqualGUID( &IID_IUnknown
, riid
) ) {
651 IDirect3DExecuteBuffer_AddRef(ICOM_INTERFACE(This
, IDirect3DExecuteBuffer
));
653 TRACE(" Creating IUnknown interface at %p.\n", *obp
);
656 if ( IsEqualGUID( &IID_IDirect3DMaterial
, riid
) ) {
657 IDirect3DExecuteBuffer_AddRef(ICOM_INTERFACE(This
, IDirect3DExecuteBuffer
));
658 *obp
= ICOM_INTERFACE(This
, IDirect3DExecuteBuffer
);
659 TRACE(" Creating IDirect3DExecuteBuffer interface %p\n", *obp
);
662 FIXME("(%p): interface for IID %s NOT found!\n", This
, debugstr_guid(riid
));
663 return OLE_E_ENUM_NOMORE
;
667 Main_IDirect3DExecuteBufferImpl_1_AddRef(LPDIRECT3DEXECUTEBUFFER iface
)
669 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
670 FIXME("(%p/%p)->()incrementing from %lu.\n", This
, iface
, This
->ref
);
671 return ++(This
->ref
);
675 Main_IDirect3DExecuteBufferImpl_1_Release(LPDIRECT3DEXECUTEBUFFER iface
)
677 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
678 TRACE("(%p/%p)->()decrementing from %lu.\n", This
, iface
, This
->ref
);
679 if (!--(This
->ref
)) {
680 if ((This
->desc
.lpData
!= NULL
) && This
->need_free
)
681 HeapFree(GetProcessHeap(),0,This
->desc
.lpData
);
682 if (This
->vertex_data
!= NULL
)
683 HeapFree(GetProcessHeap(),0,This
->vertex_data
);
684 HeapFree(GetProcessHeap(),0,This
);
692 Main_IDirect3DExecuteBufferImpl_1_Initialize(LPDIRECT3DEXECUTEBUFFER iface
,
693 LPDIRECT3DDEVICE lpDirect3DDevice
,
694 LPD3DEXECUTEBUFFERDESC lpDesc
)
696 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
697 TRACE("(%p/%p)->(%p,%p) no-op....\n", This
, iface
, lpDirect3DDevice
, lpDesc
);
702 Main_IDirect3DExecuteBufferImpl_1_Lock(LPDIRECT3DEXECUTEBUFFER iface
,
703 LPD3DEXECUTEBUFFERDESC lpDesc
)
705 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
707 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpDesc
);
709 dwSize
= lpDesc
->dwSize
;
710 memset(lpDesc
, 0, dwSize
);
711 memcpy(lpDesc
, &This
->desc
, dwSize
);
713 if (TRACE_ON(ddraw
)) {
714 TRACE(" Returning description : \n");
715 _dump_D3DEXECUTEBUFFERDESC(lpDesc
);
721 Main_IDirect3DExecuteBufferImpl_1_Unlock(LPDIRECT3DEXECUTEBUFFER iface
)
723 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
724 TRACE("(%p/%p)->() no-op...\n", This
, iface
);
729 Main_IDirect3DExecuteBufferImpl_1_SetExecuteData(LPDIRECT3DEXECUTEBUFFER iface
,
730 LPD3DEXECUTEDATA lpData
)
732 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
734 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpData
);
736 memcpy(&This
->data
, lpData
, lpData
->dwSize
);
738 /* Get the number of vertices in the execute buffer */
739 nbvert
= This
->data
.dwVertexCount
;
741 /* Prepares the transformed vertex buffer */
742 if (This
->vertex_data
!= NULL
)
743 HeapFree(GetProcessHeap(), 0, This
->vertex_data
);
744 This
->vertex_data
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, nbvert
* sizeof(OGL_Vertex
));
746 if (TRACE_ON(ddraw
)) {
747 _dump_executedata(lpData
);
754 Main_IDirect3DExecuteBufferImpl_1_GetExecuteData(LPDIRECT3DEXECUTEBUFFER iface
,
755 LPD3DEXECUTEDATA lpData
)
757 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
759 TRACE("(%p/%p)->(%p): stub!\n", This
, iface
, lpData
);
761 dwSize
= lpData
->dwSize
;
762 memset(lpData
, 0, dwSize
);
763 memcpy(lpData
, &This
->data
, dwSize
);
765 if (TRACE_ON(ddraw
)) {
766 TRACE("Returning data : \n");
767 _dump_executedata(lpData
);
774 Main_IDirect3DExecuteBufferImpl_1_Validate(LPDIRECT3DEXECUTEBUFFER iface
,
776 LPD3DVALIDATECALLBACK lpFunc
,
780 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
781 FIXME("(%p/%p)->(%p,%p,%p,%08lx): stub!\n", This
, iface
, lpdwOffset
, lpFunc
, lpUserArg
, dwReserved
);
786 Main_IDirect3DExecuteBufferImpl_1_Optimize(LPDIRECT3DEXECUTEBUFFER iface
,
789 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
790 TRACE("(%p/%p)->(%08lx) no-op...\n", This
, iface
, dwDummy
);
794 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
795 # define XCAST(fun) (typeof(VTABLE_IDirect3DExecuteBuffer.fun))
797 # define XCAST(fun) (void*)
800 ICOM_VTABLE(IDirect3DExecuteBuffer
) VTABLE_IDirect3DExecuteBuffer
=
802 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
803 XCAST(QueryInterface
) Main_IDirect3DExecuteBufferImpl_1_QueryInterface
,
804 XCAST(AddRef
) Main_IDirect3DExecuteBufferImpl_1_AddRef
,
805 XCAST(Release
) Main_IDirect3DExecuteBufferImpl_1_Release
,
806 XCAST(Initialize
) Main_IDirect3DExecuteBufferImpl_1_Initialize
,
807 XCAST(Lock
) Main_IDirect3DExecuteBufferImpl_1_Lock
,
808 XCAST(Unlock
) Main_IDirect3DExecuteBufferImpl_1_Unlock
,
809 XCAST(SetExecuteData
) Main_IDirect3DExecuteBufferImpl_1_SetExecuteData
,
810 XCAST(GetExecuteData
) Main_IDirect3DExecuteBufferImpl_1_GetExecuteData
,
811 XCAST(Validate
) Main_IDirect3DExecuteBufferImpl_1_Validate
,
812 XCAST(Optimize
) Main_IDirect3DExecuteBufferImpl_1_Optimize
,
815 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
820 HRESULT
d3dexecutebuffer_create(IDirect3DExecuteBufferImpl
**obj
, IDirect3DImpl
*d3d
, IDirect3DDeviceImpl
*d3ddev
, LPD3DEXECUTEBUFFERDESC lpDesc
)
822 IDirect3DExecuteBufferImpl
* object
;
824 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DExecuteBufferImpl
));
826 ICOM_INIT_INTERFACE(object
, IDirect3DExecuteBuffer
, VTABLE_IDirect3DExecuteBuffer
);
830 object
->d3ddev
= d3ddev
;
832 /* Initializes memory */
833 memcpy(&object
->desc
, lpDesc
, lpDesc
->dwSize
);
835 /* No buffer given */
836 if ((object
->desc
.dwFlags
& D3DDEB_LPDATA
) == 0)
837 object
->desc
.lpData
= NULL
;
839 /* No buffer size given */
840 if ((lpDesc
->dwFlags
& D3DDEB_BUFSIZE
) == 0)
841 object
->desc
.dwBufferSize
= 0;
843 /* Create buffer if asked */
844 if ((object
->desc
.lpData
== NULL
) && (object
->desc
.dwBufferSize
> 0)) {
845 object
->need_free
= TRUE
;
846 object
->desc
.lpData
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,object
->desc
.dwBufferSize
);
848 object
->need_free
= FALSE
;
851 /* No vertices for the moment */
852 object
->vertex_data
= NULL
;
854 object
->desc
.dwFlags
|= D3DDEB_LPDATA
;
856 object
->execute
= execute
;
860 TRACE(" creating implementation at %p.\n", *obj
);