xref: /reactos/dll/directx/wine/d3dx9_36/line.c (revision 84ccccab)
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 }
311