* Sync up to trunk HEAD (r62975).
[reactos.git] / 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 struct d3dx9_line
23 {
24 ID3DXLine ID3DXLine_iface;
25 LONG ref;
26
27 IDirect3DDevice9 *device;
28 IDirect3DStateBlock9 *state;
29 };
30
31 static inline struct d3dx9_line *impl_from_ID3DXLine(ID3DXLine *iface)
32 {
33 return CONTAINING_RECORD(iface, struct d3dx9_line, ID3DXLine_iface);
34 }
35
36 static HRESULT WINAPI d3dx9_line_QueryInterface(ID3DXLine *iface, REFIID riid, void **out)
37 {
38 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
39
40 if (IsEqualGUID(riid, &IID_ID3DXLine)
41 || IsEqualGUID(riid, &IID_IUnknown))
42 {
43 ID3DXLine_AddRef(iface);
44 *out = iface;
45 return S_OK;
46 }
47
48 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
49
50 *out = NULL;
51 return E_NOINTERFACE;
52 }
53
54 static ULONG WINAPI d3dx9_line_AddRef(ID3DXLine *iface)
55 {
56 struct d3dx9_line *line = impl_from_ID3DXLine(iface);
57 ULONG refcount = InterlockedIncrement(&line->ref);
58
59 TRACE("%p increasing refcount to %u.\n", line, refcount);
60
61 return refcount;
62 }
63
64 static ULONG WINAPI d3dx9_line_Release(ID3DXLine *iface)
65 {
66 struct d3dx9_line *line = impl_from_ID3DXLine(iface);
67 ULONG refcount = InterlockedDecrement(&line->ref);
68
69 TRACE("%p decreasing refcount to %u.\n", line, refcount);
70
71 if (!refcount)
72 {
73 IDirect3DDevice9_Release(line->device);
74 HeapFree(GetProcessHeap(), 0, line);
75 }
76
77 return refcount;
78 }
79
80 static HRESULT WINAPI d3dx9_line_GetDevice(struct ID3DXLine *iface, struct IDirect3DDevice9 **device)
81 {
82 struct d3dx9_line *line = impl_from_ID3DXLine(iface);
83
84 TRACE("iface %p, device %p.\n", iface, line);
85
86 if (!device)
87 return D3DERR_INVALIDCALL;
88
89 *device = line->device;
90 IDirect3DDevice9_AddRef(line->device);
91
92 return D3D_OK;
93 }
94
95 static HRESULT WINAPI d3dx9_line_Begin(ID3DXLine *iface)
96 {
97 struct d3dx9_line *line = impl_from_ID3DXLine(iface);
98 D3DXMATRIX identity, projection;
99 D3DVIEWPORT9 vp;
100
101 TRACE("iface %p.\n", iface);
102
103 if (line->state)
104 return D3DERR_INVALIDCALL;
105
106 if (FAILED(IDirect3DDevice9_CreateStateBlock(line->device, D3DSBT_ALL, &line->state)))
107 return D3DXERR_INVALIDDATA;
108
109 if (FAILED(IDirect3DDevice9_GetViewport(line->device, &vp)))
110 goto failed;
111
112 D3DXMatrixIdentity(&identity);
113 D3DXMatrixOrthoOffCenterLH(&projection, 0.0, (FLOAT)vp.Width, (FLOAT)vp.Height, 0.0, 0.0, 1.0);
114
115 if (FAILED(IDirect3DDevice9_SetTransform(line->device, D3DTS_WORLD, &identity)))
116 goto failed;
117 if (FAILED(IDirect3DDevice9_SetTransform(line->device, D3DTS_VIEW, &identity)))
118 goto failed;
119 if (FAILED(IDirect3DDevice9_SetTransform(line->device, D3DTS_PROJECTION, &projection)))
120 goto failed;
121
122 if (FAILED(IDirect3DDevice9_SetRenderState(line->device, D3DRS_LIGHTING, FALSE)))
123 goto failed;
124 if (FAILED(IDirect3DDevice9_SetRenderState(line->device, D3DRS_FOGENABLE, FALSE)))
125 goto failed;
126 if (FAILED(IDirect3DDevice9_SetRenderState(line->device, D3DRS_SHADEMODE, D3DSHADE_FLAT)))
127 goto failed;
128 if (FAILED(IDirect3DDevice9_SetRenderState(line->device, D3DRS_ALPHABLENDENABLE, TRUE)))
129 goto failed;
130 if (FAILED(IDirect3DDevice9_SetRenderState(line->device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA)))
131 goto failed;
132 if (FAILED(IDirect3DDevice9_SetRenderState(line->device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA)))
133 goto failed;
134
135 return D3D_OK;
136
137 failed:
138 IDirect3DStateBlock9_Apply(line->state);
139 IDirect3DStateBlock9_Release(line->state);
140 line->state = NULL;
141 return D3DXERR_INVALIDDATA;
142 }
143
144 static HRESULT WINAPI d3dx9_line_Draw(ID3DXLine *iface, const D3DXVECTOR2 *vertex_list,
145 DWORD vertex_list_count, D3DCOLOR color)
146 {
147 FIXME("iface %p, vertex_list %p, vertex_list_count %u, color 0x%08x stub!\n",
148 iface, vertex_list, vertex_list_count, color);
149
150 return E_NOTIMPL;
151 }
152
153 static HRESULT WINAPI d3dx9_line_DrawTransform(ID3DXLine *iface, const D3DXVECTOR3 *vertex_list,
154 DWORD vertex_list_count, const D3DXMATRIX *transform, D3DCOLOR color)
155 {
156 FIXME("iface %p, vertex_list %p, vertex_list_count %u, transform %p, color 0x%08x stub!\n",
157 iface, vertex_list, vertex_list_count, transform, color);
158
159 return E_NOTIMPL;
160 }
161
162 static HRESULT WINAPI d3dx9_line_SetPattern(ID3DXLine *iface, DWORD pattern)
163 {
164 FIXME("iface %p, pattern 0x%08x stub!\n", iface, pattern);
165
166 return E_NOTIMPL;
167 }
168
169 static DWORD WINAPI d3dx9_line_GetPattern(ID3DXLine *iface)
170 {
171 FIXME("iface %p stub!\n", iface);
172
173 return 0xffffffff;
174 }
175
176 static HRESULT WINAPI d3dx9_line_SetPatternScale(ID3DXLine *iface, float scale)
177 {
178 FIXME("iface %p, scale %.8e stub!\n", iface, scale);
179
180 return E_NOTIMPL;
181 }
182
183 static float WINAPI d3dx9_line_GetPatternScale(ID3DXLine *iface)
184 {
185 FIXME("iface %p stub!\n", iface);
186
187 return 1.0f;
188 }
189
190 static HRESULT WINAPI d3dx9_line_SetWidth(ID3DXLine *iface, float width)
191 {
192 FIXME("iface %p, width %.8e stub!\n", iface, width);
193
194 return E_NOTIMPL;
195 }
196
197 static float WINAPI d3dx9_line_GetWidth(ID3DXLine *iface)
198 {
199 FIXME("iface %p stub!\n", iface);
200
201 return 1.0f;
202 }
203
204 static HRESULT WINAPI d3dx9_line_SetAntialias(ID3DXLine *iface, BOOL antialias)
205 {
206 FIXME("iface %p, antialias %#x stub!\n", iface, antialias);
207
208 return E_NOTIMPL;
209 }
210
211 static BOOL WINAPI d3dx9_line_GetAntialias(ID3DXLine *iface)
212 {
213 FIXME("iface %p stub!\n", iface);
214
215 return FALSE;
216 }
217
218 static HRESULT WINAPI d3dx9_line_SetGLLines(ID3DXLine *iface, BOOL gl_lines)
219 {
220 FIXME("iface %p, gl_lines %#x stub!\n", iface, gl_lines);
221
222 return E_NOTIMPL;
223 }
224
225 static BOOL WINAPI d3dx9_line_GetGLLines(ID3DXLine *iface)
226 {
227 FIXME("iface %p stub!\n", iface);
228
229 return FALSE;
230 }
231
232 static HRESULT WINAPI d3dx9_line_End(ID3DXLine *iface)
233 {
234 struct d3dx9_line *line = impl_from_ID3DXLine(iface);
235
236 HRESULT hr;
237
238 TRACE("iface %p.\n", iface);
239
240 if (!line->state)
241 return D3DERR_INVALIDCALL;
242
243 hr = IDirect3DStateBlock9_Apply(line->state);
244 IDirect3DStateBlock9_Release(line->state);
245 line->state = NULL;
246
247 if (FAILED(hr))
248 return D3DXERR_INVALIDDATA;
249
250 return D3D_OK;
251 }
252
253 static HRESULT WINAPI d3dx9_line_OnLostDevice(ID3DXLine *iface)
254 {
255 FIXME("iface %p stub!\n", iface);
256
257 return E_NOTIMPL;
258 }
259 static HRESULT WINAPI d3dx9_line_OnResetDevice(ID3DXLine *iface)
260 {
261 FIXME("iface %p stub!\n", iface);
262
263 return E_NOTIMPL;
264 }
265
266 static const struct ID3DXLineVtbl d3dx9_line_vtbl =
267 {
268 d3dx9_line_QueryInterface,
269 d3dx9_line_AddRef,
270 d3dx9_line_Release,
271 d3dx9_line_GetDevice,
272 d3dx9_line_Begin,
273 d3dx9_line_Draw,
274 d3dx9_line_DrawTransform,
275 d3dx9_line_SetPattern,
276 d3dx9_line_GetPattern,
277 d3dx9_line_SetPatternScale,
278 d3dx9_line_GetPatternScale,
279 d3dx9_line_SetWidth,
280 d3dx9_line_GetWidth,
281 d3dx9_line_SetAntialias,
282 d3dx9_line_GetAntialias,
283 d3dx9_line_SetGLLines,
284 d3dx9_line_GetGLLines,
285 d3dx9_line_End,
286 d3dx9_line_OnLostDevice,
287 d3dx9_line_OnResetDevice,
288 };
289
290 HRESULT WINAPI D3DXCreateLine(struct IDirect3DDevice9 *device, struct ID3DXLine **line)
291 {
292 struct d3dx9_line *object;
293
294 TRACE("device %p, line %p.\n", device, line);
295
296 if (!device || !line)
297 return D3DERR_INVALIDCALL;
298
299 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
300 return E_OUTOFMEMORY;
301
302 object->ID3DXLine_iface.lpVtbl = &d3dx9_line_vtbl;
303 object->ref = 1;
304 object->device = device;
305 IDirect3DDevice9_AddRef(device);
306
307 *line = &object->ID3DXLine_iface;
308
309 return D3D_OK;
310 }