cac954e71f2944b2e16b278d34e4d7645de75b46
[reactos.git] / reactos / dll / directx / wine / d3dx9_36 / line.c
1 /*
2 * Copyright 2010 Christian Costa
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 *
18 */
19
20 #include "d3dx9_36_private.h"
21
22 typedef struct ID3DXLineImpl {
23 ID3DXLine ID3DXLine_iface;
24 LONG ref;
25
26 IDirect3DDevice9 *device;
27 IDirect3DStateBlock9 *state;
28 } ID3DXLineImpl;
29
30 static inline ID3DXLineImpl *impl_from_ID3DXLine(ID3DXLine *iface)
31 {
32 return CONTAINING_RECORD(iface, ID3DXLineImpl, ID3DXLine_iface);
33 }
34
35 /*** IUnknown methods ***/
36 static HRESULT WINAPI ID3DXLineImpl_QueryInterface(ID3DXLine* iface, REFIID riid, LPVOID* object)
37 {
38 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), object);
39
40 if (IsEqualGUID(riid, &IID_IUnknown) ||
41 IsEqualGUID(riid, &IID_ID3DXLine))
42 {
43 ID3DXLine_AddRef(iface);
44 *object = iface;
45 return S_OK;
46 }
47
48 ERR("Interface %s not found\n", debugstr_guid(riid));
49
50 return E_NOINTERFACE;
51 }
52
53 static ULONG WINAPI ID3DXLineImpl_AddRef(ID3DXLine* iface)
54 {
55 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
56
57 TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
58
59 return InterlockedIncrement(&This->ref);
60 }
61
62 static ULONG WINAPI ID3DXLineImpl_Release(ID3DXLine* iface)
63 {
64 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
65 ULONG ref = InterlockedDecrement(&This->ref);
66
67 TRACE("(%p)->(): Release from %u\n", This, ref + 1);
68
69 if (!ref)
70 {
71 IDirect3DDevice9_Release(This->device);
72 HeapFree(GetProcessHeap(), 0, This);
73 }
74
75 return ref;
76 }
77
78 /*** ID3DXLine methods ***/
79 static HRESULT WINAPI ID3DXLineImpl_GetDevice(struct ID3DXLine *iface, struct IDirect3DDevice9 **device)
80 {
81 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
82
83 TRACE ("(%p)->(%p)\n", This, device);
84
85 if (device == NULL) return D3DERR_INVALIDCALL;
86
87 *device = This->device;
88 IDirect3DDevice9_AddRef(This->device);
89
90 return D3D_OK;
91 }
92
93 static HRESULT WINAPI ID3DXLineImpl_Begin(ID3DXLine* iface)
94 {
95 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
96
97 HRESULT hr;
98 D3DXMATRIX identity, projection;
99 D3DVIEWPORT9 vp;
100
101 TRACE ("(%p)->()\n", This);
102
103 if (This->state != NULL) /* We already began. Return error. */
104 return D3DERR_INVALIDCALL;
105
106 hr = IDirect3DDevice9_CreateStateBlock(This->device, D3DSBT_ALL, &This->state);
107 if (FAILED(hr)) return D3DXERR_INVALIDDATA;
108
109 hr = IDirect3DDevice9_GetViewport(This->device, &vp);
110 if (FAILED(hr)) goto failed;
111
112 D3DXMatrixIdentity(&identity);
113 D3DXMatrixOrthoOffCenterLH(&projection,
114 0.0, vp.Width, /* Min and max x */
115 vp.Height, 0.0, /* Min and max y. Screen y is on top so this is inverted */
116 0.0, 1.0); /* Min and max z */
117
118 hr = IDirect3DDevice9_SetTransform(This->device, D3DTS_WORLD, &identity);
119 if (FAILED(hr)) goto failed;
120
121 hr = IDirect3DDevice9_SetTransform(This->device, D3DTS_VIEW, &identity);
122 if (FAILED(hr)) goto failed;
123
124 hr = IDirect3DDevice9_SetTransform(This->device, D3DTS_PROJECTION, &projection);
125 if (FAILED(hr)) goto failed;
126
127 /* Windows sets similar states so we do the same */
128
129 hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_LIGHTING, FALSE);
130 if (FAILED(hr)) goto failed;
131
132 hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_FOGENABLE, FALSE);
133 if (FAILED(hr)) goto failed;
134
135 hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_SHADEMODE, D3DSHADE_FLAT);
136 if (FAILED(hr)) goto failed;
137
138 hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_ALPHABLENDENABLE, TRUE);
139 if (FAILED(hr)) goto failed;
140
141 hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
142 if (FAILED(hr)) goto failed;
143
144 hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
145 if (FAILED(hr)) goto failed;
146
147 return D3D_OK;
148 failed:
149 IDirect3DStateBlock9_Apply(This->state);
150 IDirect3DStateBlock9_Release(This->state);
151 This->state = NULL;
152 return D3DXERR_INVALIDDATA;
153 }
154
155 static HRESULT WINAPI ID3DXLineImpl_Draw(ID3DXLine* iface, CONST D3DXVECTOR2* vertexlist, DWORD vertexlistcount, D3DCOLOR color)
156 {
157 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
158
159 FIXME("(%p)->(%p, %u, %#x): stub\n", This, vertexlist, vertexlistcount, color);
160
161 return E_NOTIMPL;
162 }
163
164 static HRESULT WINAPI ID3DXLineImpl_DrawTransform(ID3DXLine* iface, CONST D3DXVECTOR3* vertexlist, DWORD vertexlistcount,
165 CONST D3DXMATRIX* transform, D3DCOLOR color)
166 {
167 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
168
169 FIXME("(%p)->(%p, %u, %p, %#x): stub\n", This, vertexlist, vertexlistcount, transform, color);
170
171 return E_NOTIMPL;
172 }
173
174 static HRESULT WINAPI ID3DXLineImpl_SetPattern(ID3DXLine* iface, DWORD pattern)
175 {
176 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
177
178 FIXME("(%p)->(%#x): stub\n", This, pattern);
179
180 return E_NOTIMPL;
181 }
182
183 static DWORD WINAPI ID3DXLineImpl_GetPattern(ID3DXLine* iface)
184 {
185 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
186
187 FIXME("(%p)->(): stub\n", This);
188
189 return 0xFFFFFFFF;
190 }
191
192 static HRESULT WINAPI ID3DXLineImpl_SetPatternScale(ID3DXLine* iface, FLOAT scale)
193 {
194 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
195
196 FIXME("(%p)->(%f): stub\n", This, scale);
197
198 return E_NOTIMPL;
199 }
200
201 static FLOAT WINAPI ID3DXLineImpl_GetPatternScale(ID3DXLine* iface)
202 {
203 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
204
205 FIXME("(%p)->(): stub\n", This);
206
207 return 1.0f;
208 }
209
210 static HRESULT WINAPI ID3DXLineImpl_SetWidth(ID3DXLine* iface, FLOAT width)
211 {
212 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
213
214 FIXME("(%p)->(%f): stub\n", This, width);
215
216 return E_NOTIMPL;
217 }
218
219 static FLOAT WINAPI ID3DXLineImpl_GetWidth(ID3DXLine* iface)
220 {
221 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
222
223 FIXME("(%p)->(): stub\n", This);
224
225 return 1.0f;
226 }
227
228 static HRESULT WINAPI ID3DXLineImpl_SetAntialias(ID3DXLine* iface, BOOL antialias)
229 {
230 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
231
232 FIXME("(%p)->(%u): stub\n", This, antialias);
233
234 return E_NOTIMPL;
235 }
236
237 static BOOL WINAPI ID3DXLineImpl_GetAntialias(ID3DXLine* iface)
238 {
239 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
240
241 FIXME("(%p)->(): stub\n", This);
242
243 return FALSE;
244 }
245
246 static HRESULT WINAPI ID3DXLineImpl_SetGLLines(ID3DXLine* iface, BOOL gl_lines)
247 {
248 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
249
250 FIXME("(%p)->(%u): stub\n", This, gl_lines);
251
252 return E_NOTIMPL;
253 }
254
255 static BOOL WINAPI ID3DXLineImpl_GetGLLines(ID3DXLine* iface)
256 {
257 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
258
259 FIXME("(%p)->(): stub\n", This);
260
261 return FALSE;
262 }
263
264 static HRESULT WINAPI ID3DXLineImpl_End(ID3DXLine* iface)
265 {
266 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
267
268 HRESULT hr;
269
270 TRACE ("(%p)->()\n", This);
271
272 if (This->state == NULL) /* We haven't begun yet. */
273 return D3DERR_INVALIDCALL;
274
275 hr = IDirect3DStateBlock9_Apply(This->state);
276 IDirect3DStateBlock9_Release(This->state);
277 This->state = NULL;
278
279 if (FAILED(hr)) return D3DXERR_INVALIDDATA;
280 else return D3D_OK;
281 }
282
283 static HRESULT WINAPI ID3DXLineImpl_OnLostDevice(ID3DXLine* iface)
284 {
285 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
286
287 FIXME("(%p)->(): stub\n", This);
288
289 return E_NOTIMPL;
290 }
291 static HRESULT WINAPI ID3DXLineImpl_OnResetDevice(ID3DXLine* iface)
292 {
293 ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
294
295 FIXME("(%p)->(): stub\n", This);
296
297 return E_NOTIMPL;
298 }
299
300 static const struct ID3DXLineVtbl ID3DXLine_Vtbl =
301 {
302 /*** IUnknown methods ***/
303 ID3DXLineImpl_QueryInterface,
304 ID3DXLineImpl_AddRef,
305 ID3DXLineImpl_Release,
306 /*** ID3DXLine methods ***/
307 ID3DXLineImpl_GetDevice,
308 ID3DXLineImpl_Begin,
309 ID3DXLineImpl_Draw,
310 ID3DXLineImpl_DrawTransform,
311 ID3DXLineImpl_SetPattern,
312 ID3DXLineImpl_GetPattern,
313 ID3DXLineImpl_SetPatternScale,
314 ID3DXLineImpl_GetPatternScale,
315 ID3DXLineImpl_SetWidth,
316 ID3DXLineImpl_GetWidth,
317 ID3DXLineImpl_SetAntialias,
318 ID3DXLineImpl_GetAntialias,
319 ID3DXLineImpl_SetGLLines,
320 ID3DXLineImpl_GetGLLines,
321 ID3DXLineImpl_End,
322 ID3DXLineImpl_OnLostDevice,
323 ID3DXLineImpl_OnResetDevice
324 };
325
326 HRESULT WINAPI D3DXCreateLine(struct IDirect3DDevice9 *device, struct ID3DXLine **line)
327 {
328 ID3DXLineImpl* object;
329
330 TRACE("(%p, %p)\n", device, line);
331
332 if (!device || !line)
333 return D3DERR_INVALIDCALL;
334
335 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ID3DXLineImpl));
336 if (!object)
337 return E_OUTOFMEMORY;
338
339 object->ID3DXLine_iface.lpVtbl = &ID3DXLine_Vtbl;
340 object->ref = 1;
341 object->device = device;
342 object->state = NULL; /* We only initialize it on Begin */
343 IDirect3DDevice9_AddRef(device);
344
345 *line = &object->ID3DXLine_iface;
346
347 return D3D_OK;
348 }