Adapted to the interface/implementation separation.
[wine] / graphics / d3dcommon.c
1 /* Direct3D Common functions
2    (c) 1998 Lionel ULMER
3    
4    This file contains all common miscellaneous code that spans
5    different 'objects' */
6
7 #include "windef.h"
8 #include "wine/obj_base.h"
9 #include "ddraw.h"
10 #include "d3d.h"
11 #include "debug.h"
12
13 #include "d3d_private.h"
14
15 #ifdef HAVE_MESAGL
16
17 static void _dump_renderstate(D3DRENDERSTATETYPE type,
18                               DWORD value) {
19   char *states[] = {
20     NULL,
21     "D3DRENDERSTATE_TEXTUREHANDLE",
22     "D3DRENDERSTATE_ANTIALIAS",
23     "D3DRENDERSTATE_TEXTUREADDRESS",
24     "D3DRENDERSTATE_TEXTUREPERSPECTIVE",
25     "D3DRENDERSTATE_WRAPU",
26     "D3DRENDERSTATE_WRAPV",
27     "D3DRENDERSTATE_ZENABLE",
28     "D3DRENDERSTATE_FILLMODE",
29     "D3DRENDERSTATE_SHADEMODE",
30     "D3DRENDERSTATE_LINEPATTERN",
31     "D3DRENDERSTATE_MONOENABLE",
32     "D3DRENDERSTATE_ROP2",
33     "D3DRENDERSTATE_PLANEMASK",
34     "D3DRENDERSTATE_ZWRITEENABLE",
35     "D3DRENDERSTATE_ALPHATESTENABLE",
36     "D3DRENDERSTATE_LASTPIXEL",
37     "D3DRENDERSTATE_TEXTUREMAG",
38     "D3DRENDERSTATE_TEXTUREMIN",
39     "D3DRENDERSTATE_SRCBLEND",
40     "D3DRENDERSTATE_DESTBLEND",
41     "D3DRENDERSTATE_TEXTUREMAPBLEND",
42     "D3DRENDERSTATE_CULLMODE",
43     "D3DRENDERSTATE_ZFUNC",
44     "D3DRENDERSTATE_ALPHAREF",
45     "D3DRENDERSTATE_ALPHAFUNC",
46     "D3DRENDERSTATE_DITHERENABLE",
47     "D3DRENDERSTATE_ALPHABLENDENABLE",
48     "D3DRENDERSTATE_FOGENABLE",
49     "D3DRENDERSTATE_SPECULARENABLE",
50     "D3DRENDERSTATE_ZVISIBLE",
51     "D3DRENDERSTATE_SUBPIXEL",
52     "D3DRENDERSTATE_SUBPIXELX",
53     "D3DRENDERSTATE_STIPPLEDALPHA",
54     "D3DRENDERSTATE_FOGCOLOR",
55     "D3DRENDERSTATE_FOGTABLEMODE",
56     "D3DRENDERSTATE_FOGTABLESTART",
57     "D3DRENDERSTATE_FOGTABLEEND",
58     "D3DRENDERSTATE_FOGTABLEDENSITY",
59     "D3DRENDERSTATE_STIPPLEENABLE",
60     "D3DRENDERSTATE_EDGEANTIALIAS",
61     "D3DRENDERSTATE_COLORKEYENABLE",
62     "ERR",
63     "D3DRENDERSTATE_BORDERCOLOR",
64     "D3DRENDERSTATE_TEXTUREADDRESSU",
65     "D3DRENDERSTATE_TEXTUREADDRESSV",
66     "D3DRENDERSTATE_MIPMAPLODBIAS",
67     "D3DRENDERSTATE_ZBIAS",
68     "D3DRENDERSTATE_RANGEFOGENABLE",
69     "D3DRENDERSTATE_ANISOTROPY",
70     "D3DRENDERSTATE_FLUSHBATCH",
71     "ERR", "ERR", "ERR", "ERR", "ERR", "ERR", "ERR",
72     "ERR", "ERR", "ERR", "ERR", "ERR", "ERR",
73     "D3DRENDERSTATE_STIPPLEPATTERN00",
74     "D3DRENDERSTATE_STIPPLEPATTERN01",
75     "D3DRENDERSTATE_STIPPLEPATTERN02",
76     "D3DRENDERSTATE_STIPPLEPATTERN03",
77     "D3DRENDERSTATE_STIPPLEPATTERN04",
78     "D3DRENDERSTATE_STIPPLEPATTERN05",
79     "D3DRENDERSTATE_STIPPLEPATTERN06",
80     "D3DRENDERSTATE_STIPPLEPATTERN07",
81     "D3DRENDERSTATE_STIPPLEPATTERN08",
82     "D3DRENDERSTATE_STIPPLEPATTERN09",
83     "D3DRENDERSTATE_STIPPLEPATTERN10",
84     "D3DRENDERSTATE_STIPPLEPATTERN11",
85     "D3DRENDERSTATE_STIPPLEPATTERN12",
86     "D3DRENDERSTATE_STIPPLEPATTERN13",
87     "D3DRENDERSTATE_STIPPLEPATTERN14",
88     "D3DRENDERSTATE_STIPPLEPATTERN15",
89     "D3DRENDERSTATE_STIPPLEPATTERN16",
90     "D3DRENDERSTATE_STIPPLEPATTERN17",
91     "D3DRENDERSTATE_STIPPLEPATTERN18",
92     "D3DRENDERSTATE_STIPPLEPATTERN19",
93     "D3DRENDERSTATE_STIPPLEPATTERN20",
94     "D3DRENDERSTATE_STIPPLEPATTERN21",
95     "D3DRENDERSTATE_STIPPLEPATTERN22",
96     "D3DRENDERSTATE_STIPPLEPATTERN23",
97     "D3DRENDERSTATE_STIPPLEPATTERN24",
98     "D3DRENDERSTATE_STIPPLEPATTERN25",
99     "D3DRENDERSTATE_STIPPLEPATTERN26",
100     "D3DRENDERSTATE_STIPPLEPATTERN27",
101     "D3DRENDERSTATE_STIPPLEPATTERN28",
102     "D3DRENDERSTATE_STIPPLEPATTERN29",
103     "D3DRENDERSTATE_STIPPLEPATTERN30",
104     "D3DRENDERSTATE_STIPPLEPATTERN31"
105   };
106
107   DUMP(" %s = 0x%08lx\n", states[type], value);
108 }
109
110
111 void set_render_state(D3DRENDERSTATETYPE dwRenderStateType,
112                       DWORD dwRenderState, RenderState *rs)
113 {
114
115   if (TRACE_ON(ddraw))
116     _dump_renderstate(dwRenderStateType, dwRenderState);
117
118   /* First, all the stipple patterns */
119   if ((dwRenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00) && 
120       (dwRenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)) {
121     ERR(ddraw, "Unhandled stipple !\n");
122   } else {
123     /* All others state variables */
124     switch (dwRenderStateType) {
125
126     case D3DRENDERSTATE_TEXTUREHANDLE: {    /*  1 */
127       IDirect3DTexture2Impl* tex = (IDirect3DTexture2Impl*) dwRenderState;
128       
129       if (tex == NULL) {
130         glBindTexture(GL_TEXTURE_2D, 0);
131         glDisable(GL_TEXTURE_2D);
132       } else {
133         TRACE(ddraw, "setting OpenGL texture handle : %d\n", tex->tex_name);
134         glEnable(GL_TEXTURE_2D);
135         /* Default parameters */
136         glBindTexture(GL_TEXTURE_2D, tex->tex_name);
137         /* To prevent state change, we could test here what are the parameters
138            stored in the texture */
139         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, rs->mag);
140         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, rs->min);
141       }
142     } break;
143
144     case D3DRENDERSTATE_TEXTUREPERSPECTIVE: /* 4 */
145       if (dwRenderState)
146         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
147       else
148         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
149       break;
150       
151     case D3DRENDERSTATE_ZENABLE:          /*  7 */
152       if (dwRenderState)
153         glEnable(GL_DEPTH_TEST);
154       else
155         glDisable(GL_DEPTH_TEST);
156       break;
157       
158     case D3DRENDERSTATE_FILLMODE:           /*  8 */
159       switch ((D3DFILLMODE) dwRenderState) {
160       case D3DFILL_SOLID:
161         break;
162
163       default:
164         ERR(ddraw, "Unhandled fill mode !\n");
165       }
166       break;
167
168     case D3DRENDERSTATE_SHADEMODE:          /*  9 */
169       switch ((D3DSHADEMODE) dwRenderState) {
170       case D3DSHADE_FLAT:
171         glShadeModel(GL_FLAT);
172         break;
173
174       case D3DSHADE_GOURAUD:
175         glShadeModel(GL_SMOOTH);
176         break;
177
178       default:
179         ERR(ddraw, "Unhandled shade mode !\n");
180       }
181       break;
182       
183     case D3DRENDERSTATE_ZWRITEENABLE:     /* 14 */
184       if (dwRenderState)
185         glDepthMask(GL_TRUE);
186       else
187         glDepthMask(GL_FALSE);
188       break;
189       
190     case D3DRENDERSTATE_TEXTUREMAG:         /* 17 */
191       switch ((D3DTEXTUREFILTER) dwRenderState) {
192       case D3DFILTER_NEAREST:
193         rs->mag = GL_NEAREST;
194         break;
195         
196       case D3DFILTER_LINEAR:
197         rs->mag = GL_LINEAR;
198         break;
199         
200       default:
201         ERR(ddraw, "Unhandled texture mag !\n");
202       }
203       break;
204
205     case D3DRENDERSTATE_TEXTUREMIN:         /* 18 */
206       switch ((D3DTEXTUREFILTER) dwRenderState) {
207       case D3DFILTER_NEAREST:
208         rs->min = GL_NEAREST;
209         break;
210         
211       case D3DFILTER_LINEAR:
212         rs->mag = GL_LINEAR;
213         break;
214         
215       default:
216         ERR(ddraw, "Unhandled texture min !\n");
217       }
218       break;
219       
220     case D3DRENDERSTATE_SRCBLEND:           /* 19 */
221       switch ((D3DBLEND) dwRenderState) {
222       case D3DBLEND_SRCALPHA:
223         rs->src = GL_SRC_ALPHA;
224         break;
225
226       default:
227         ERR(ddraw, "Unhandled blend mode !\n");
228       }
229       
230       glBlendFunc(rs->src, rs->dst);
231       break;
232       
233     case D3DRENDERSTATE_DESTBLEND:          /* 20 */
234       switch ((D3DBLEND) dwRenderState) {
235       case D3DBLEND_INVSRCALPHA:
236         rs->dst = GL_ONE_MINUS_SRC_ALPHA;
237         break;
238         
239       default:
240         ERR(ddraw, "Unhandled blend mode !\n");
241       }
242       
243       glBlendFunc(rs->src, rs->dst);
244       break;
245
246     case D3DRENDERSTATE_TEXTUREMAPBLEND:    /* 21 */
247       switch ((D3DTEXTUREBLEND) dwRenderState) {
248       case D3DTBLEND_MODULATE:
249       case D3DTBLEND_MODULATEALPHA:
250         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
251         break;
252
253       default:
254         ERR(ddraw, "Unhandled texture environment !\n");
255       }
256       break;
257       
258     case D3DRENDERSTATE_CULLMODE:           /* 22 */
259       switch ((D3DCULL) dwRenderState) {
260       case D3DCULL_NONE:
261         glDisable(GL_CULL_FACE);
262         break;
263         
264       case D3DCULL_CW:
265         glEnable(GL_CULL_FACE);
266         glFrontFace(GL_CW);
267         break;
268         
269       case D3DCULL_CCW:
270         glEnable(GL_CULL_FACE);
271         glFrontFace(GL_CCW);
272         break;
273         
274       default:
275         ERR(ddraw, "Unhandled cull mode !\n");
276       }
277       break;
278       
279     case D3DRENDERSTATE_ZFUNC:            /* 23 */
280       switch ((D3DCMPFUNC) dwRenderState) {
281       case D3DCMP_NEVER:
282         glDepthFunc(GL_NEVER);
283         break;
284       case D3DCMP_LESS:
285         glDepthFunc(GL_LESS);
286         break;
287       case D3DCMP_EQUAL:
288         glDepthFunc(GL_EQUAL);
289         break;
290       case D3DCMP_LESSEQUAL:
291         glDepthFunc(GL_LEQUAL);
292         break;
293       case D3DCMP_GREATER:
294         glDepthFunc(GL_GREATER);
295         break;
296       case D3DCMP_NOTEQUAL:
297         glDepthFunc(GL_NOTEQUAL);
298         break;
299       case D3DCMP_GREATEREQUAL:
300         glDepthFunc(GL_GEQUAL);
301         break;
302       case D3DCMP_ALWAYS:
303         glDepthFunc(GL_ALWAYS);
304         break;
305
306       default:
307         ERR(ddraw, "Unexpected value\n");
308       }
309       break;
310       
311     case D3DRENDERSTATE_DITHERENABLE:     /* 26 */
312       if (dwRenderState)
313         glEnable(GL_DITHER);
314       else
315         glDisable(GL_DITHER);
316       break;
317       
318     case D3DRENDERSTATE_ALPHABLENDENABLE:   /* 27 */
319       if (dwRenderState)
320         glEnable(GL_BLEND);
321       else
322         glDisable(GL_BLEND);
323       break;
324
325     case D3DRENDERSTATE_COLORKEYENABLE:     /* 41 */
326       if (dwRenderState)
327         glEnable(GL_BLEND);
328       else
329         glDisable(GL_BLEND);
330       break;
331
332     case D3DRENDERSTATE_FLUSHBATCH:         /* 50 */
333       break;
334       
335     default:
336       ERR(ddraw, "Unhandled Render State\n");
337       break;
338     }
339   }
340 }
341
342
343 #endif /* HAVE_MESAGL */