For better concurrency, separate the connections from the bindings.
[wine.git] / dlls / ddraw / d3dcommon.c
blobbd3ab341b715ba0df5a9a9e04a576ddd374cae01
1 /* Direct3D Common functions
2 * Copyright (c) 1998 Lionel ULMER
4 * This file contains all common miscellaneous code that spans
5 * different 'objects'
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #define NONAMELESSUNION
23 #define NONAMELESSSTRUCT
24 #include "windef.h"
25 #include "objbase.h"
26 #include "ddraw.h"
27 #include "d3d.h"
28 #include "wine/debug.h"
30 #include "d3d_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
34 const char *_get_renderstate(D3DRENDERSTATETYPE type) {
35 static const char * const states[] = {
36 "ERR",
37 "D3DRENDERSTATE_TEXTUREHANDLE",
38 "D3DRENDERSTATE_ANTIALIAS",
39 "D3DRENDERSTATE_TEXTUREADDRESS",
40 "D3DRENDERSTATE_TEXTUREPERSPECTIVE",
41 "D3DRENDERSTATE_WRAPU",
42 "D3DRENDERSTATE_WRAPV",
43 "D3DRENDERSTATE_ZENABLE",
44 "D3DRENDERSTATE_FILLMODE",
45 "D3DRENDERSTATE_SHADEMODE",
46 "D3DRENDERSTATE_LINEPATTERN",
47 "D3DRENDERSTATE_MONOENABLE",
48 "D3DRENDERSTATE_ROP2",
49 "D3DRENDERSTATE_PLANEMASK",
50 "D3DRENDERSTATE_ZWRITEENABLE",
51 "D3DRENDERSTATE_ALPHATESTENABLE",
52 "D3DRENDERSTATE_LASTPIXEL",
53 "D3DRENDERSTATE_TEXTUREMAG",
54 "D3DRENDERSTATE_TEXTUREMIN",
55 "D3DRENDERSTATE_SRCBLEND",
56 "D3DRENDERSTATE_DESTBLEND",
57 "D3DRENDERSTATE_TEXTUREMAPBLEND",
58 "D3DRENDERSTATE_CULLMODE",
59 "D3DRENDERSTATE_ZFUNC",
60 "D3DRENDERSTATE_ALPHAREF",
61 "D3DRENDERSTATE_ALPHAFUNC",
62 "D3DRENDERSTATE_DITHERENABLE",
63 "D3DRENDERSTATE_ALPHABLENDENABLE",
64 "D3DRENDERSTATE_FOGENABLE",
65 "D3DRENDERSTATE_SPECULARENABLE",
66 "D3DRENDERSTATE_ZVISIBLE",
67 "D3DRENDERSTATE_SUBPIXEL",
68 "D3DRENDERSTATE_SUBPIXELX",
69 "D3DRENDERSTATE_STIPPLEDALPHA",
70 "D3DRENDERSTATE_FOGCOLOR",
71 "D3DRENDERSTATE_FOGTABLEMODE",
72 "D3DRENDERSTATE_FOGTABLESTART",
73 "D3DRENDERSTATE_FOGTABLEEND",
74 "D3DRENDERSTATE_FOGTABLEDENSITY",
75 "D3DRENDERSTATE_STIPPLEENABLE",
76 "D3DRENDERSTATE_EDGEANTIALIAS",
77 "D3DRENDERSTATE_COLORKEYENABLE",
78 "ERR",
79 "D3DRENDERSTATE_BORDERCOLOR",
80 "D3DRENDERSTATE_TEXTUREADDRESSU",
81 "D3DRENDERSTATE_TEXTUREADDRESSV",
82 "D3DRENDERSTATE_MIPMAPLODBIAS",
83 "D3DRENDERSTATE_ZBIAS",
84 "D3DRENDERSTATE_RANGEFOGENABLE",
85 "D3DRENDERSTATE_ANISOTROPY",
86 "D3DRENDERSTATE_FLUSHBATCH",
87 "D3DRENDERSTATE_TRANSLUCENTSORTINDEPENDENT",
88 "D3DRENDERSTATE_STENCILENABLE",
89 "D3DRENDERSTATE_STENCILFAIL",
90 "D3DRENDERSTATE_STENCILZFAIL",
91 "D3DRENDERSTATE_STENCILPASS",
92 "D3DRENDERSTATE_STENCILFUNC",
93 "D3DRENDERSTATE_STENCILREF",
94 "D3DRENDERSTATE_STENCILMASK",
95 "D3DRENDERSTATE_STENCILWRITEMASK",
96 "D3DRENDERSTATE_TEXTUREFACTOR",
97 "ERR",
98 "ERR",
99 "ERR",
100 "D3DRENDERSTATE_STIPPLEPATTERN00",
101 "D3DRENDERSTATE_STIPPLEPATTERN01",
102 "D3DRENDERSTATE_STIPPLEPATTERN02",
103 "D3DRENDERSTATE_STIPPLEPATTERN03",
104 "D3DRENDERSTATE_STIPPLEPATTERN04",
105 "D3DRENDERSTATE_STIPPLEPATTERN05",
106 "D3DRENDERSTATE_STIPPLEPATTERN06",
107 "D3DRENDERSTATE_STIPPLEPATTERN07",
108 "D3DRENDERSTATE_STIPPLEPATTERN08",
109 "D3DRENDERSTATE_STIPPLEPATTERN09",
110 "D3DRENDERSTATE_STIPPLEPATTERN10",
111 "D3DRENDERSTATE_STIPPLEPATTERN11",
112 "D3DRENDERSTATE_STIPPLEPATTERN12",
113 "D3DRENDERSTATE_STIPPLEPATTERN13",
114 "D3DRENDERSTATE_STIPPLEPATTERN14",
115 "D3DRENDERSTATE_STIPPLEPATTERN15",
116 "D3DRENDERSTATE_STIPPLEPATTERN16",
117 "D3DRENDERSTATE_STIPPLEPATTERN17",
118 "D3DRENDERSTATE_STIPPLEPATTERN18",
119 "D3DRENDERSTATE_STIPPLEPATTERN19",
120 "D3DRENDERSTATE_STIPPLEPATTERN20",
121 "D3DRENDERSTATE_STIPPLEPATTERN21",
122 "D3DRENDERSTATE_STIPPLEPATTERN22",
123 "D3DRENDERSTATE_STIPPLEPATTERN23",
124 "D3DRENDERSTATE_STIPPLEPATTERN24",
125 "D3DRENDERSTATE_STIPPLEPATTERN25",
126 "D3DRENDERSTATE_STIPPLEPATTERN26",
127 "D3DRENDERSTATE_STIPPLEPATTERN27",
128 "D3DRENDERSTATE_STIPPLEPATTERN28",
129 "D3DRENDERSTATE_STIPPLEPATTERN29",
130 "D3DRENDERSTATE_STIPPLEPATTERN30",
131 "D3DRENDERSTATE_STIPPLEPATTERN31"
133 static const char * const states_2[] = {
134 "D3DRENDERSTATE_WRAP0",
135 "D3DRENDERSTATE_WRAP1",
136 "D3DRENDERSTATE_WRAP2",
137 "D3DRENDERSTATE_WRAP3",
138 "D3DRENDERSTATE_WRAP4",
139 "D3DRENDERSTATE_WRAP5",
140 "D3DRENDERSTATE_WRAP6",
141 "D3DRENDERSTATE_WRAP7",
142 "D3DRENDERSTATE_CLIPPING",
143 "D3DRENDERSTATE_LIGHTING",
144 "D3DRENDERSTATE_EXTENTS",
145 "D3DRENDERSTATE_AMBIENT",
146 "D3DRENDERSTATE_FOGVERTEXMODE",
147 "D3DRENDERSTATE_COLORVERTEX",
148 "D3DRENDERSTATE_LOCALVIEWER",
149 "D3DRENDERSTATE_NORMALIZENORMALS",
150 "D3DRENDERSTATE_COLORKEYBLENDENABLE",
151 "D3DRENDERSTATE_DIFFUSEMATERIALSOURCE",
152 "D3DRENDERSTATE_SPECULARMATERIALSOURCE",
153 "D3DRENDERSTATE_AMBIENTMATERIALSOURCE",
154 "D3DRENDERSTATE_EMISSIVEMATERIALSOURCE",
155 "ERR",
156 "ERR",
157 "D3DRENDERSTATE_VERTEXBLEND",
158 "D3DRENDERSTATE_CLIPPLANEENABLE",
160 if (type >= D3DRENDERSTATE_WRAP0) {
161 type -= D3DRENDERSTATE_WRAP0;
162 if (type >= (sizeof(states_2) / sizeof(states_2[0]))) return "ERR";
163 return states_2[type];
165 if (type >= (sizeof(states) / sizeof(states[0]))) return "ERR";
166 return states[type];
169 void
170 dump_D3DCOLORVALUE(D3DCOLORVALUE *lpCol)
172 DPRINTF("%f %f %f %f", lpCol->u1.r, lpCol->u2.g, lpCol->u3.b, lpCol->u4.a);
175 void
176 dump_D3DVECTOR(D3DVECTOR *lpVec)
178 DPRINTF("%f %f %f", lpVec->u1.x, lpVec->u2.y, lpVec->u3.z);
181 void
182 dump_D3DMATERIAL7(LPD3DMATERIAL7 lpMat)
184 DPRINTF(" - diffuse : "); dump_D3DCOLORVALUE(&(lpMat->u.diffuse)); DPRINTF("\n");
185 DPRINTF(" - ambient : "); dump_D3DCOLORVALUE(&(lpMat->u1.ambient)); DPRINTF("\n");
186 DPRINTF(" - specular : "); dump_D3DCOLORVALUE(&(lpMat->u2.specular)); DPRINTF("\n");
187 DPRINTF(" - emissive : "); dump_D3DCOLORVALUE(&(lpMat->u3.emissive)); DPRINTF("\n");
188 DPRINTF(" - power : %f\n", lpMat->u4.power);
191 void
192 dump_D3DLIGHT7(LPD3DLIGHT7 lpLight)
194 DPRINTF(" - light type : %s\n", (lpLight->dltType == D3DLIGHT_POINT ? "D3DLIGHT_POINT" :
195 (lpLight->dltType == D3DLIGHT_SPOT ? "D3DLIGHT_SPOT" :
196 (lpLight->dltType == D3DLIGHT_DIRECTIONAL ? "D3DLIGHT_DIRECTIONAL" :
197 "UNSUPPORTED"))));
198 DPRINTF(" - diffuse : "); dump_D3DCOLORVALUE(&(lpLight->dcvDiffuse)); DPRINTF("\n");
199 DPRINTF(" - specular : "); dump_D3DCOLORVALUE(&(lpLight->dcvSpecular)); DPRINTF("\n");
200 DPRINTF(" - ambient : "); dump_D3DCOLORVALUE(&(lpLight->dcvAmbient)); DPRINTF("\n");
201 DPRINTF(" - position : "); dump_D3DVECTOR(&(lpLight->dvPosition)); DPRINTF("\n");
202 DPRINTF(" - direction : "); dump_D3DVECTOR(&(lpLight->dvDirection)); DPRINTF("\n");
203 DPRINTF(" - dvRange : %f\n", lpLight->dvRange);
204 DPRINTF(" - dvFalloff : %f\n", lpLight->dvFalloff);
205 DPRINTF(" - dvAttenuation : %f %f %f\n", lpLight->dvAttenuation0, lpLight->dvAttenuation1, lpLight->dvAttenuation2);
206 DPRINTF(" - dvTheta : %f\n", lpLight->dvTheta);
207 DPRINTF(" - dvPhi : %f\n", lpLight->dvPhi);
210 void
211 dump_DPFLAGS(DWORD dwFlags)
213 static const flag_info flags[] =
215 FE(D3DDP_WAIT),
216 FE(D3DDP_OUTOFORDER),
217 FE(D3DDP_DONOTCLIP),
218 FE(D3DDP_DONOTUPDATEEXTENTS),
219 FE(D3DDP_DONOTLIGHT)
222 DDRAW_dump_flags(dwFlags, flags, sizeof(flags)/sizeof(flags[0]));
225 void
226 dump_D3DMATRIX(D3DMATRIX *mat)
228 DPRINTF(" %f %f %f %f\n", mat->_11, mat->_12, mat->_13, mat->_14);
229 DPRINTF(" %f %f %f %f\n", mat->_21, mat->_22, mat->_23, mat->_24);
230 DPRINTF(" %f %f %f %f\n", mat->_31, mat->_32, mat->_33, mat->_34);
231 DPRINTF(" %f %f %f %f\n", mat->_41, mat->_42, mat->_43, mat->_44);
235 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType)
237 DWORD size = 0;
239 if (d3dvtVertexType & D3DFVF_NORMAL) size += 3 * sizeof(D3DVALUE);
240 if (d3dvtVertexType & D3DFVF_DIFFUSE) size += sizeof(DWORD);
241 if (d3dvtVertexType & D3DFVF_SPECULAR) size += sizeof(DWORD);
242 if (d3dvtVertexType & D3DFVF_RESERVED1) size += sizeof(DWORD);
243 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
244 case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); break;
245 case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); break;
246 default: TRACE(" matrix weighting not handled yet...\n");
248 size += 2 * sizeof(D3DVALUE) * ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT);
250 return size;
253 void dump_flexible_vertex(DWORD d3dvtVertexType)
255 static const flag_info flags[] = {
256 FE(D3DFVF_NORMAL),
257 FE(D3DFVF_RESERVED1),
258 FE(D3DFVF_DIFFUSE),
259 FE(D3DFVF_SPECULAR)
261 int i;
263 if (d3dvtVertexType & D3DFVF_RESERVED0) DPRINTF("D3DFVF_RESERVED0 ");
264 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
265 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
266 GEN_CASE(D3DFVF_XYZ);
267 GEN_CASE(D3DFVF_XYZRHW);
268 GEN_CASE(D3DFVF_XYZB1);
269 GEN_CASE(D3DFVF_XYZB2);
270 GEN_CASE(D3DFVF_XYZB3);
271 GEN_CASE(D3DFVF_XYZB4);
272 GEN_CASE(D3DFVF_XYZB5);
274 DDRAW_dump_flags_(d3dvtVertexType, flags, sizeof(flags)/sizeof(flags[0]), FALSE);
275 switch (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) {
276 GEN_CASE(D3DFVF_TEX0);
277 GEN_CASE(D3DFVF_TEX1);
278 GEN_CASE(D3DFVF_TEX2);
279 GEN_CASE(D3DFVF_TEX3);
280 GEN_CASE(D3DFVF_TEX4);
281 GEN_CASE(D3DFVF_TEX5);
282 GEN_CASE(D3DFVF_TEX6);
283 GEN_CASE(D3DFVF_TEX7);
284 GEN_CASE(D3DFVF_TEX8);
286 #undef GEN_CASE
287 for (i = 0; i < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); i++) {
288 DPRINTF(" T%d-s%ld", i + 1, (((d3dvtVertexType >> (16 + (2 * i))) + 1) & 0x03) + 1);
290 DPRINTF("\n");
293 void
294 convert_FVF_to_strided_data(DWORD d3dvtVertexType, LPVOID lpvVertices, D3DDRAWPRIMITIVESTRIDEDDATA *strided, DWORD dwStartVertex)
296 int current_offset = 0;
297 int tex_index;
298 int size = get_flexible_vertex_size(d3dvtVertexType);
300 lpvVertices = ((BYTE *) lpvVertices) + (size * dwStartVertex);
302 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
303 strided->position.lpvData = lpvVertices;
304 current_offset += 3 * sizeof(D3DVALUE);
305 } else {
306 strided->position.lpvData = lpvVertices;
307 current_offset += 4 * sizeof(D3DVALUE);
309 if (d3dvtVertexType & D3DFVF_RESERVED1) {
310 current_offset += sizeof(DWORD);
312 if (d3dvtVertexType & D3DFVF_NORMAL) {
313 strided->normal.lpvData = ((char *) lpvVertices) + current_offset;
314 current_offset += 3 * sizeof(D3DVALUE);
316 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
317 strided->diffuse.lpvData = ((char *) lpvVertices) + current_offset;
318 current_offset += sizeof(DWORD);
320 if (d3dvtVertexType & D3DFVF_SPECULAR) {
321 strided->specular.lpvData = ((char *) lpvVertices) + current_offset;
322 current_offset += sizeof(DWORD);
324 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
325 strided->textureCoords[tex_index].lpvData = ((char *) lpvVertices) + current_offset;
326 current_offset += 2 * sizeof(D3DVALUE);
328 strided->position.dwStride = current_offset;
329 strided->normal.dwStride = current_offset;
330 strided->diffuse.dwStride = current_offset;
331 strided->specular.dwStride = current_offset;
332 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++)
333 strided->textureCoords[tex_index].dwStride = current_offset;
336 void
337 dump_D3DVOP(DWORD dwVertexOp)
339 static const flag_info flags[] =
341 FE(D3DVOP_LIGHT),
342 FE(D3DVOP_CLIP),
343 FE(D3DVOP_EXTENTS),
344 FE(D3DVOP_TRANSFORM)
346 DDRAW_dump_flags(dwVertexOp, flags, sizeof(flags)/sizeof(flags[0]));
349 void
350 dump_D3DPV(DWORD dwFlags)
352 if (dwFlags == D3DPV_DONOTCOPYDATA) DPRINTF("D3DPV_DONOTCOPYDATA\n");
353 else if (dwFlags != 0) DPRINTF("Unknown !!!\n");
354 else DPRINTF("\n");