1 | /* $Id: d3d9render.cpp 98909 2023-03-10 16:49:13Z vboxsync $ */
|
---|
2 | /** @file
|
---|
3 | * Gallium D3D testcase. Simple D3D9 tests.
|
---|
4 | */
|
---|
5 |
|
---|
6 | /*
|
---|
7 | * Copyright (C) 2017-2023 Oracle and/or its affiliates.
|
---|
8 | *
|
---|
9 | * This file is part of VirtualBox base platform packages, as
|
---|
10 | * available from https://www.virtualbox.org.
|
---|
11 | *
|
---|
12 | * This program is free software; you can redistribute it and/or
|
---|
13 | * modify it under the terms of the GNU General Public License
|
---|
14 | * as published by the Free Software Foundation, in version 3 of the
|
---|
15 | * License.
|
---|
16 | *
|
---|
17 | * This program is distributed in the hope that it will be useful, but
|
---|
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
20 | * General Public License for more details.
|
---|
21 | *
|
---|
22 | * You should have received a copy of the GNU General Public License
|
---|
23 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
24 | *
|
---|
25 | * SPDX-License-Identifier: GPL-3.0-only
|
---|
26 | */
|
---|
27 |
|
---|
28 | #include "d3d9render.h"
|
---|
29 |
|
---|
30 | #include <intrin.h>
|
---|
31 |
|
---|
32 | static HRESULT d3dCopyToVertexBuffer(IDirect3DVertexBuffer9 *pVB, const void *pvSrc, int cbSrc)
|
---|
33 | {
|
---|
34 | HRESULT hr = D3D_OK;
|
---|
35 | void *pvDst = 0;
|
---|
36 | HTEST(pVB->Lock(0, 0, &pvDst, 0));
|
---|
37 | if (SUCCEEDED(hr))
|
---|
38 | {
|
---|
39 | memcpy(pvDst, pvSrc, cbSrc);
|
---|
40 | HTEST(pVB->Unlock());
|
---|
41 | }
|
---|
42 | return hr;
|
---|
43 | }
|
---|
44 |
|
---|
45 | static HRESULT d3dCopyToIndexBuffer(IDirect3DIndexBuffer9 *pIB, const void *pvSrc, int cbSrc)
|
---|
46 | {
|
---|
47 | HRESULT hr = D3D_OK;
|
---|
48 | void *pvDst = 0;
|
---|
49 | HTEST(pIB->Lock(0, 0, &pvDst, 0));
|
---|
50 | if (SUCCEEDED(hr))
|
---|
51 | {
|
---|
52 | memcpy(pvDst, pvSrc, cbSrc);
|
---|
53 | HTEST(pIB->Unlock());
|
---|
54 | }
|
---|
55 | return hr;
|
---|
56 | }
|
---|
57 |
|
---|
58 | static void drawTexture(IDirect3DDevice9 *pDevice, IDirect3DTexture9 *pTexture, int x, int y, int w, int h)
|
---|
59 | {
|
---|
60 | HRESULT hr = S_OK;
|
---|
61 |
|
---|
62 | HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET, 0xffafaf00, 0.0f, 0));
|
---|
63 |
|
---|
64 | HTEST(pDevice->BeginScene());
|
---|
65 |
|
---|
66 | IDirect3DSurface9 *pSurface;
|
---|
67 | HTEST(pTexture->GetSurfaceLevel(0, &pSurface));
|
---|
68 |
|
---|
69 | /* Copy the texture to the backbuffer. */
|
---|
70 | IDirect3DSurface9 *pBackBuffer;
|
---|
71 | HTEST(pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer));
|
---|
72 |
|
---|
73 | RECT rDst;
|
---|
74 | rDst.left = x;
|
---|
75 | rDst.top = y;
|
---|
76 | rDst.right = x + w;
|
---|
77 | rDst.bottom = y + h;
|
---|
78 |
|
---|
79 | HTEST(pDevice->StretchRect(pSurface, NULL, pBackBuffer, &rDst, D3DTEXF_POINT));
|
---|
80 |
|
---|
81 | HTEST(pDevice->EndScene());
|
---|
82 |
|
---|
83 | D3D_RELEASE(pBackBuffer);
|
---|
84 | D3D_RELEASE(pSurface);
|
---|
85 | }
|
---|
86 |
|
---|
87 |
|
---|
88 | /*
|
---|
89 | * Clear the backbuffer and display it.
|
---|
90 | */
|
---|
91 |
|
---|
92 | class D3D9RenderClear: public D3D9Render
|
---|
93 | {
|
---|
94 | public:
|
---|
95 | D3D9RenderClear() {}
|
---|
96 | virtual ~D3D9RenderClear() {}
|
---|
97 | virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
|
---|
98 | virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
|
---|
99 | };
|
---|
100 |
|
---|
101 | HRESULT D3D9RenderClear::InitRender(D3D9DeviceProvider *pDP)
|
---|
102 | {
|
---|
103 | (void)pDP;
|
---|
104 | return S_OK;
|
---|
105 | }
|
---|
106 |
|
---|
107 | HRESULT D3D9RenderClear::DoRender(D3D9DeviceProvider *pDP)
|
---|
108 | {
|
---|
109 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
110 |
|
---|
111 | pDevice->Clear(0, 0, D3DCLEAR_TARGET /* | D3DCLEAR_ZBUFFER */, 0xff0000ff, 1.0f, 0);
|
---|
112 |
|
---|
113 | /* Separately test depth. This triggered a unimplemented code path in SVGA driver. */
|
---|
114 | D3DRECT r;
|
---|
115 | r.x1 = 20;
|
---|
116 | r.y1 = 20;
|
---|
117 | r.x2 = 120;
|
---|
118 | r.y2 = 120;
|
---|
119 | pDevice->Clear(1, &r, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
|
---|
120 |
|
---|
121 | pDevice->Present(0, 0, 0, 0);
|
---|
122 | return S_OK;
|
---|
123 | }
|
---|
124 |
|
---|
125 |
|
---|
126 | /*
|
---|
127 | * Minimal code to draw a black triangle.
|
---|
128 | */
|
---|
129 |
|
---|
130 | class D3D9RenderTriangle: public D3D9Render
|
---|
131 | {
|
---|
132 | public:
|
---|
133 | D3D9RenderTriangle();
|
---|
134 | virtual ~D3D9RenderTriangle();
|
---|
135 | virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
|
---|
136 | virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
|
---|
137 | private:
|
---|
138 | IDirect3DVertexDeclaration9 *mpVertexDecl;
|
---|
139 | IDirect3DVertexBuffer9 *mpVB;
|
---|
140 |
|
---|
141 | struct Vertex
|
---|
142 | {
|
---|
143 | D3DVECTOR position;
|
---|
144 | };
|
---|
145 |
|
---|
146 | static D3DVERTEXELEMENT9 maVertexElements[];
|
---|
147 | };
|
---|
148 |
|
---|
149 | D3DVERTEXELEMENT9 D3D9RenderTriangle::maVertexElements[] =
|
---|
150 | {
|
---|
151 | { 0, GA_W_OFFSET_OF(Vertex, position), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
|
---|
152 | D3DDECL_END()
|
---|
153 | };
|
---|
154 |
|
---|
155 | D3D9RenderTriangle::D3D9RenderTriangle()
|
---|
156 | :
|
---|
157 | mpVertexDecl(0),
|
---|
158 | mpVB(0)
|
---|
159 | {
|
---|
160 | }
|
---|
161 |
|
---|
162 | D3D9RenderTriangle::~D3D9RenderTriangle()
|
---|
163 | {
|
---|
164 | D3D_RELEASE(mpVertexDecl);
|
---|
165 | D3D_RELEASE(mpVB);
|
---|
166 | }
|
---|
167 |
|
---|
168 | HRESULT D3D9RenderTriangle::InitRender(D3D9DeviceProvider *pDP)
|
---|
169 | {
|
---|
170 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
171 |
|
---|
172 | HRESULT hr = pDevice->CreateVertexDeclaration(maVertexElements, &mpVertexDecl);
|
---|
173 | if (FAILED(hr))
|
---|
174 | {
|
---|
175 | return hr;
|
---|
176 | }
|
---|
177 |
|
---|
178 | /* Coords are choosen to avoid setting the view and projection matrices. */
|
---|
179 | static Vertex aVertices[] =
|
---|
180 | {
|
---|
181 | { {-0.5f, -0.5f, 0.9f } },
|
---|
182 | { { 0.0f, 0.5f, 0.9f } },
|
---|
183 | { { 0.5f, -0.5f, 0.9f } },
|
---|
184 | };
|
---|
185 |
|
---|
186 | hr = pDevice->CreateVertexBuffer(sizeof(aVertices), 0, 0, D3DPOOL_DEFAULT, &mpVB, 0);
|
---|
187 | if (FAILED(hr))
|
---|
188 | {
|
---|
189 | return hr;
|
---|
190 | }
|
---|
191 |
|
---|
192 | hr = d3dCopyToVertexBuffer(mpVB, aVertices, sizeof(aVertices));
|
---|
193 |
|
---|
194 | return hr;
|
---|
195 | }
|
---|
196 |
|
---|
197 | HRESULT D3D9RenderTriangle::DoRender(D3D9DeviceProvider *pDP)
|
---|
198 | {
|
---|
199 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
200 |
|
---|
201 | HRESULT hr = S_OK;
|
---|
202 |
|
---|
203 | HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0));
|
---|
204 |
|
---|
205 | HTEST(pDevice->BeginScene());
|
---|
206 |
|
---|
207 | HTEST(pDevice->SetStreamSource(0, mpVB, 0, sizeof(Vertex)));
|
---|
208 | HTEST(pDevice->SetVertexDeclaration(mpVertexDecl));
|
---|
209 |
|
---|
210 | HTEST(pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1));
|
---|
211 |
|
---|
212 | HTEST(pDevice->EndScene());
|
---|
213 |
|
---|
214 | HTEST(pDevice->Present(0, 0, 0, 0));
|
---|
215 | return S_OK;
|
---|
216 | }
|
---|
217 |
|
---|
218 |
|
---|
219 | /*
|
---|
220 | * Colorful triangle using FVF.
|
---|
221 | */
|
---|
222 |
|
---|
223 | class D3D9RenderTriangleFVF: public D3D9Render
|
---|
224 | {
|
---|
225 | public:
|
---|
226 | D3D9RenderTriangleFVF();
|
---|
227 | virtual ~D3D9RenderTriangleFVF();
|
---|
228 | virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
|
---|
229 | virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
|
---|
230 | private:
|
---|
231 | IDirect3DVertexBuffer9 *mpVB;
|
---|
232 |
|
---|
233 | struct Vertex_XYZRHW_DIFFUSE
|
---|
234 | {
|
---|
235 | FLOAT x, y, z, rhw;
|
---|
236 | DWORD color;
|
---|
237 | };
|
---|
238 | };
|
---|
239 |
|
---|
240 | #define FVF_XYZRHW_DIFFUSE (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
|
---|
241 |
|
---|
242 | D3D9RenderTriangleFVF::D3D9RenderTriangleFVF()
|
---|
243 | :
|
---|
244 | mpVB(0)
|
---|
245 | {
|
---|
246 | }
|
---|
247 |
|
---|
248 | D3D9RenderTriangleFVF::~D3D9RenderTriangleFVF()
|
---|
249 | {
|
---|
250 | D3D_RELEASE(mpVB);
|
---|
251 | }
|
---|
252 |
|
---|
253 | HRESULT D3D9RenderTriangleFVF::InitRender(D3D9DeviceProvider *pDP)
|
---|
254 | {
|
---|
255 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
256 |
|
---|
257 | static Vertex_XYZRHW_DIFFUSE aVertices[] =
|
---|
258 | {
|
---|
259 | { 50.0f, 50.0f, 0.5f, 1.0f, D3DCOLOR_XRGB( 0, 0, 255), },
|
---|
260 | { 150.0f, 50.0f, 0.5f, 1.0f, D3DCOLOR_XRGB( 0, 255, 0), },
|
---|
261 | { 100.0f, 150.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), },
|
---|
262 | };
|
---|
263 |
|
---|
264 | HRESULT hr = S_OK;
|
---|
265 |
|
---|
266 | HTEST(pDevice->CreateVertexBuffer(sizeof(aVertices),
|
---|
267 | 0,
|
---|
268 | FVF_XYZRHW_DIFFUSE,
|
---|
269 | D3DPOOL_DEFAULT,
|
---|
270 | &mpVB,
|
---|
271 | 0));
|
---|
272 | if (FAILED(hr))
|
---|
273 | {
|
---|
274 | return hr;
|
---|
275 | }
|
---|
276 |
|
---|
277 | HTEST(d3dCopyToVertexBuffer(mpVB, aVertices, sizeof(aVertices)));
|
---|
278 |
|
---|
279 | return hr;
|
---|
280 | }
|
---|
281 |
|
---|
282 | HRESULT D3D9RenderTriangleFVF::DoRender(D3D9DeviceProvider *pDP)
|
---|
283 | {
|
---|
284 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
285 |
|
---|
286 | HRESULT hr = S_OK;
|
---|
287 |
|
---|
288 | HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffafafaf, 1.0f, 0));
|
---|
289 |
|
---|
290 | HTEST(pDevice->BeginScene());
|
---|
291 |
|
---|
292 | HTEST(pDevice->SetStreamSource(0, mpVB, 0, sizeof(Vertex_XYZRHW_DIFFUSE)));
|
---|
293 | HTEST(pDevice->SetFVF(FVF_XYZRHW_DIFFUSE));
|
---|
294 |
|
---|
295 | HTEST(pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1));
|
---|
296 |
|
---|
297 | HTEST(pDevice->EndScene());
|
---|
298 |
|
---|
299 | HTEST(pDevice->Present(0, 0, 0, 0));
|
---|
300 | return S_OK;
|
---|
301 | }
|
---|
302 |
|
---|
303 |
|
---|
304 | /*
|
---|
305 | * Colorful triangle using shaders.
|
---|
306 | */
|
---|
307 |
|
---|
308 | class D3D9RenderTriangleShader: public D3D9Render
|
---|
309 | {
|
---|
310 | public:
|
---|
311 | D3D9RenderTriangleShader();
|
---|
312 | virtual ~D3D9RenderTriangleShader();
|
---|
313 | virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
|
---|
314 | virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
|
---|
315 | private:
|
---|
316 | IDirect3DVertexBuffer9 *mpVB;
|
---|
317 | IDirect3DVertexDeclaration9 *mpVertexDecl;
|
---|
318 | IDirect3DVertexShader9 *mpVS;
|
---|
319 | IDirect3DPixelShader9 *mpPS;
|
---|
320 |
|
---|
321 | struct Vertex
|
---|
322 | {
|
---|
323 | D3DVECTOR position;
|
---|
324 | D3DCOLOR color;
|
---|
325 | };
|
---|
326 | static D3DVERTEXELEMENT9 VertexElements[];
|
---|
327 | };
|
---|
328 |
|
---|
329 | D3DVERTEXELEMENT9 D3D9RenderTriangleShader::VertexElements[] =
|
---|
330 | {
|
---|
331 | {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
|
---|
332 | {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
|
---|
333 | D3DDECL_END()
|
---|
334 | };
|
---|
335 |
|
---|
336 |
|
---|
337 | D3D9RenderTriangleShader::D3D9RenderTriangleShader()
|
---|
338 | :
|
---|
339 | mpVB(0),
|
---|
340 | mpVertexDecl(0),
|
---|
341 | mpVS(0),
|
---|
342 | mpPS(0)
|
---|
343 | {
|
---|
344 | }
|
---|
345 |
|
---|
346 | D3D9RenderTriangleShader::~D3D9RenderTriangleShader()
|
---|
347 | {
|
---|
348 | D3D_RELEASE(mpVS);
|
---|
349 | D3D_RELEASE(mpPS);
|
---|
350 | D3D_RELEASE(mpVB);
|
---|
351 | D3D_RELEASE(mpVertexDecl);
|
---|
352 | }
|
---|
353 |
|
---|
354 | HRESULT D3D9RenderTriangleShader::InitRender(D3D9DeviceProvider *pDP)
|
---|
355 | {
|
---|
356 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
357 |
|
---|
358 | static DWORD aVSCode[] =
|
---|
359 | {
|
---|
360 | 0xFFFE0200, // vs_2_0
|
---|
361 | 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c0, 1, 0, 0, 0
|
---|
362 | 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0
|
---|
363 | 0x0200001f, 0x8000000a, 0x900f0001, // dcl_color v1
|
---|
364 | 0x02000001, 0xc0070000, 0x90e40000, // mov oPos.xyz, v0
|
---|
365 | 0x02000001, 0xc0080000, 0xa0000000, // mov oPos.w, c0.x
|
---|
366 | 0x02000001, 0xd00f0000, 0x90e40001, // mov oD0, v1
|
---|
367 | 0x0000FFFF
|
---|
368 | };
|
---|
369 |
|
---|
370 | static DWORD aPSCode[] =
|
---|
371 | {
|
---|
372 | 0xFFFF0200, // ps_2_0
|
---|
373 | 0x0200001f, 0x80000000, 0x900f0000, // dcl v0
|
---|
374 | 0x02000001, 0x800f0800, 0x90e40000, // mov oC0, v0
|
---|
375 | 0x0000FFFF
|
---|
376 | };
|
---|
377 |
|
---|
378 | static DWORD aPSCode1[] =
|
---|
379 | {
|
---|
380 | 0xFFFF0200, // ps_2_0
|
---|
381 | 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c0, 1, 0, 0, 0
|
---|
382 | 0x02000001, 0x800f0000, 0xa0000000, // mov r0, c0.x
|
---|
383 | 0x02000001, 0x800f0800, 0x80e40000, // mov oC0, r0
|
---|
384 | 0x0000FFFF
|
---|
385 | };
|
---|
386 |
|
---|
387 | static DWORD aPSCodeParallax[] =
|
---|
388 | {
|
---|
389 | 0xFFFF0300,
|
---|
390 | 0x0200001F, 0x80010005, 0x900F0000,
|
---|
391 | 0x0200001F, 0x80020005, 0x900F0001,
|
---|
392 | 0x0200001F, 0x80030005, 0x900F0002,
|
---|
393 | 0x0200001F, 0x80040005, 0x900F0003,
|
---|
394 | 0x0200001F, 0x80050005, 0x900F0004,
|
---|
395 | 0x0200001F, 0x80060005, 0x900F0005,
|
---|
396 | 0x05000051, 0xA00F00F1, 0x3F6147AE, 0x3F451EB8, 0xBF6147AE, 0xBF451EB8,
|
---|
397 | 0x0000FFFF
|
---|
398 | };
|
---|
399 |
|
---|
400 | static Vertex aVertices[] =
|
---|
401 | {
|
---|
402 | { { -0.5f, -0.5f, 0.5f }, D3DCOLOR_XRGB( 0, 0, 255), },
|
---|
403 | { { 0.5f, -0.5f, 0.5f }, D3DCOLOR_XRGB( 0, 255, 0), },
|
---|
404 | { { 0.0f, 0.5f, 0.5f }, D3DCOLOR_XRGB(255, 0, 0), },
|
---|
405 | };
|
---|
406 |
|
---|
407 | HRESULT hr = S_OK;
|
---|
408 |
|
---|
409 | HTEST(pDevice->CreateVertexDeclaration(VertexElements, &mpVertexDecl));
|
---|
410 | HTEST(pDevice->CreateVertexBuffer(sizeof(aVertices),
|
---|
411 | 0, /* D3DUSAGE_* */
|
---|
412 | 0, /* FVF */
|
---|
413 | D3DPOOL_DEFAULT,
|
---|
414 | &mpVB,
|
---|
415 | 0));
|
---|
416 | HTEST(pDevice->CreateVertexShader(aVSCode, &mpVS));
|
---|
417 | HTEST(pDevice->CreatePixelShader(aPSCode, &mpPS));
|
---|
418 |
|
---|
419 | HTEST(d3dCopyToVertexBuffer(mpVB, aVertices, sizeof(aVertices)));
|
---|
420 |
|
---|
421 | return hr;
|
---|
422 | }
|
---|
423 |
|
---|
424 | HRESULT D3D9RenderTriangleShader::DoRender(D3D9DeviceProvider *pDP)
|
---|
425 | {
|
---|
426 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
427 |
|
---|
428 | HRESULT hr = S_OK;
|
---|
429 |
|
---|
430 | HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffafafaf, 1.0f, 0));
|
---|
431 |
|
---|
432 | HTEST(pDevice->BeginScene());
|
---|
433 |
|
---|
434 | HTEST(pDevice->SetStreamSource(0, mpVB, 0, sizeof(Vertex)));
|
---|
435 | HTEST(pDevice->SetVertexDeclaration(mpVertexDecl));
|
---|
436 | HTEST(pDevice->SetVertexShader(mpVS));
|
---|
437 | HTEST(pDevice->SetPixelShader(mpPS));
|
---|
438 | HTEST(pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
|
---|
439 |
|
---|
440 | HTEST(pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1));
|
---|
441 |
|
---|
442 | HTEST(pDevice->EndScene());
|
---|
443 |
|
---|
444 | HTEST(pDevice->Present(0, 0, 0, 0));
|
---|
445 | return S_OK;
|
---|
446 | }
|
---|
447 |
|
---|
448 |
|
---|
449 | /*
|
---|
450 | * Cubemap texture.
|
---|
451 | */
|
---|
452 |
|
---|
453 | class D3D9RenderCubeMap: public D3D9Render
|
---|
454 | {
|
---|
455 | public:
|
---|
456 | D3D9RenderCubeMap();
|
---|
457 | virtual ~D3D9RenderCubeMap();
|
---|
458 | virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
|
---|
459 | virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
|
---|
460 | virtual void TimeAdvance(float dt);
|
---|
461 |
|
---|
462 | private:
|
---|
463 | IDirect3DVertexDeclaration9 *mpVertexDecl;
|
---|
464 | IDirect3DVertexBuffer9 *mpVertexBuffer;
|
---|
465 | IDirect3DCubeTexture9 *mpCubeTexture;
|
---|
466 | IDirect3DVertexShader9 *mpVS;
|
---|
467 | IDirect3DPixelShader9 *mpPS;
|
---|
468 |
|
---|
469 | D3DCamera mCamera;
|
---|
470 |
|
---|
471 | static D3DVERTEXELEMENT9 maVertexElements[];
|
---|
472 | };
|
---|
473 |
|
---|
474 | D3DVERTEXELEMENT9 D3D9RenderCubeMap::maVertexElements[] =
|
---|
475 | {
|
---|
476 | { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
|
---|
477 | D3DDECL_END()
|
---|
478 | };
|
---|
479 |
|
---|
480 | D3D9RenderCubeMap::D3D9RenderCubeMap()
|
---|
481 | :
|
---|
482 | mpVertexDecl(0),
|
---|
483 | mpVertexBuffer(0),
|
---|
484 | mpCubeTexture(0),
|
---|
485 | mpVS(0),
|
---|
486 | mpPS(0)
|
---|
487 | {
|
---|
488 | }
|
---|
489 |
|
---|
490 | D3D9RenderCubeMap::~D3D9RenderCubeMap()
|
---|
491 | {
|
---|
492 | D3D_RELEASE(mpVS);
|
---|
493 | D3D_RELEASE(mpPS);
|
---|
494 | D3D_RELEASE(mpVertexBuffer);
|
---|
495 | D3D_RELEASE(mpVertexDecl);
|
---|
496 | D3D_RELEASE(mpCubeTexture);
|
---|
497 | }
|
---|
498 |
|
---|
499 | HRESULT D3D9RenderCubeMap::InitRender(D3D9DeviceProvider *pDP)
|
---|
500 | {
|
---|
501 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
502 |
|
---|
503 | static const DWORD aVSCubeMap[] =
|
---|
504 | {
|
---|
505 | 0xfffe0200, // vs_2_0
|
---|
506 | 0x05000051, 0xa00f0004, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c4, 1, 0, 0, 0
|
---|
507 | 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0
|
---|
508 | 0x04000004, 0x800f0000, 0x90240000, 0xa0400004, 0xa0150004, // mad r0, v0.xyzx, c4.xxxy, c4.yyyx
|
---|
509 | 0x03000009, 0x80010001, 0x80e40000, 0xa0e40000, // dp4 r1.x, r0, c0
|
---|
510 | 0x03000009, 0x80020001, 0x80e40000, 0xa0e40001, // dp4 r1.y, r0, c1
|
---|
511 | 0x03000009, 0x80040001, 0x80e40000, 0xa0e40003, // dp4 r1.z, r0, c3
|
---|
512 | 0x02000001, 0xc00f0000, 0x80a40001, // mov oPos, r1.xyzz
|
---|
513 | 0x02000001, 0xe0070000, 0x90e40000, // mov oT0.xyz, v0
|
---|
514 | 0x0000ffff
|
---|
515 | };
|
---|
516 |
|
---|
517 | static const DWORD aPSCubeMap[] =
|
---|
518 | {
|
---|
519 | 0xffff0200, // ps_2_0
|
---|
520 | 0x0200001f, 0x80000000, 0xb0070000, // dcl t0.xyz
|
---|
521 | 0x0200001f, 0x98000000, 0xa00f0800, // dcl_cube s0
|
---|
522 | 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, // texld r0, t0, s0
|
---|
523 | 0x02000001, 0x800f0800, 0x80e40000, // mov oC0, r0
|
---|
524 | 0x0000ffff
|
---|
525 | };
|
---|
526 |
|
---|
527 | HRESULT hr = S_OK;
|
---|
528 |
|
---|
529 | HTEST(pDevice->CreateVertexDeclaration(maVertexElements, &mpVertexDecl));
|
---|
530 | HTEST(d3dCreateCubeVertexBuffer(pDevice, 1.0f, &mpVertexBuffer));
|
---|
531 | HTEST(d3dCreateCubeTexture(pDevice, &mpCubeTexture));
|
---|
532 | HTEST(pDevice->CreateVertexShader(aVSCubeMap, &mpVS));
|
---|
533 | HTEST(pDevice->CreatePixelShader(aPSCubeMap, &mpPS));
|
---|
534 |
|
---|
535 | float w = 800;
|
---|
536 | float h = 600;
|
---|
537 | mCamera.SetProjection(3.14f * 0.5f, w/h, 1.0f, 100.0f);
|
---|
538 |
|
---|
539 | return S_OK;
|
---|
540 | }
|
---|
541 |
|
---|
542 | HRESULT D3D9RenderCubeMap::DoRender(D3D9DeviceProvider *pDP)
|
---|
543 | {
|
---|
544 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
545 |
|
---|
546 | HRESULT hr = S_OK;
|
---|
547 |
|
---|
548 | // HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0));
|
---|
549 |
|
---|
550 | HTEST(pDevice->BeginScene());
|
---|
551 |
|
---|
552 | /* World matrix is identity matrix, i.e. need only View and Projection. */
|
---|
553 | D3DMATRIX WVP = *mCamera.ViewProjection();
|
---|
554 | d3dMatrixTranspose(&WVP); /* Because shader will multiply vector row by matrix column, i.e. columns must be in the shader constants. */
|
---|
555 |
|
---|
556 | HTEST(pDevice->SetVertexShader(mpVS));
|
---|
557 | HTEST(pDevice->SetPixelShader(mpPS));
|
---|
558 |
|
---|
559 | HTEST(pDevice->SetVertexShaderConstantF(0, &WVP.m[0][0], 4));
|
---|
560 | HTEST(pDevice->SetTexture(0, mpCubeTexture));
|
---|
561 |
|
---|
562 | HTEST(pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
|
---|
563 | HTEST(pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS));
|
---|
564 |
|
---|
565 | HTEST(pDevice->SetVertexDeclaration(mpVertexDecl));
|
---|
566 | HTEST(pDevice->SetStreamSource(0, mpVertexBuffer, 0, 3 * sizeof(float)));
|
---|
567 |
|
---|
568 | HTEST(pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 6 * 2));
|
---|
569 |
|
---|
570 | HTEST(pDevice->EndScene());
|
---|
571 |
|
---|
572 | HTEST(pDevice->Present(0, 0, 0, 0));
|
---|
573 |
|
---|
574 | return S_OK;
|
---|
575 | }
|
---|
576 |
|
---|
577 | void D3D9RenderCubeMap::TimeAdvance(float dt)
|
---|
578 | {
|
---|
579 | mCamera.TimeAdvance(dt);
|
---|
580 | }
|
---|
581 |
|
---|
582 |
|
---|
583 | /*
|
---|
584 | * Solid triangles using shaders and instancing.
|
---|
585 | */
|
---|
586 |
|
---|
587 | class D3D9RenderInstance: public D3D9Render
|
---|
588 | {
|
---|
589 | public:
|
---|
590 | D3D9RenderInstance();
|
---|
591 | virtual ~D3D9RenderInstance();
|
---|
592 | virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
|
---|
593 | virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
|
---|
594 | private:
|
---|
595 | IDirect3DVertexBuffer9 *mpVBGeometry;
|
---|
596 | IDirect3DVertexBuffer9 *mpVBInstance;
|
---|
597 | IDirect3DIndexBuffer9 *mpIB;
|
---|
598 | IDirect3DVertexDeclaration9 *mpVertexDecl;
|
---|
599 | IDirect3DVertexShader9 *mpVS;
|
---|
600 | IDirect3DPixelShader9 *mpPS;
|
---|
601 |
|
---|
602 | struct VertexGeometry
|
---|
603 | {
|
---|
604 | D3DVECTOR position;
|
---|
605 | };
|
---|
606 |
|
---|
607 | struct VertexInstance
|
---|
608 | {
|
---|
609 | D3DCOLOR color;
|
---|
610 | float dy;
|
---|
611 | };
|
---|
612 | static D3DVERTEXELEMENT9 VertexElements[];
|
---|
613 | };
|
---|
614 |
|
---|
615 | D3DVERTEXELEMENT9 D3D9RenderInstance::VertexElements[] =
|
---|
616 | {
|
---|
617 | {0, GA_W_OFFSET_OF(VertexGeometry, position), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
|
---|
618 | {1, GA_W_OFFSET_OF(VertexInstance, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
|
---|
619 | {1, GA_W_OFFSET_OF(VertexInstance, dy), D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
|
---|
620 | D3DDECL_END()
|
---|
621 | };
|
---|
622 |
|
---|
623 |
|
---|
624 | D3D9RenderInstance::D3D9RenderInstance()
|
---|
625 | :
|
---|
626 | mpVBGeometry(0),
|
---|
627 | mpVBInstance(0),
|
---|
628 | mpIB(0),
|
---|
629 | mpVertexDecl(0),
|
---|
630 | mpVS(0),
|
---|
631 | mpPS(0)
|
---|
632 | {
|
---|
633 | }
|
---|
634 |
|
---|
635 | D3D9RenderInstance::~D3D9RenderInstance()
|
---|
636 | {
|
---|
637 | D3D_RELEASE(mpVBGeometry);
|
---|
638 | D3D_RELEASE(mpVBInstance);
|
---|
639 | D3D_RELEASE(mpIB);
|
---|
640 | D3D_RELEASE(mpVertexDecl);
|
---|
641 | D3D_RELEASE(mpVS);
|
---|
642 | D3D_RELEASE(mpPS);
|
---|
643 | }
|
---|
644 |
|
---|
645 | HRESULT D3D9RenderInstance::InitRender(D3D9DeviceProvider *pDP)
|
---|
646 | {
|
---|
647 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
648 |
|
---|
649 | static DWORD aVSCode[] =
|
---|
650 | {
|
---|
651 | 0xfffe0200, // vs_2_0
|
---|
652 | 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c0, 1, 0, 0, 0
|
---|
653 | 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0
|
---|
654 | 0x0200001f, 0x8000000a, 0x900f0001, // dcl_color v1
|
---|
655 | 0x0200001f, 0x80000005, 0x900f0002, // dcl_texcoord v2
|
---|
656 | 0x02000001, 0x80020000, 0x90550000, // mov r0.y, v0.y
|
---|
657 | 0x03000002, 0xc0020000, 0x80550000, 0x90000002, // add oPos.y, r0.y, v2.x
|
---|
658 | 0x02000001, 0xc0050000, 0x90e40000, // mov oPos.xz, v0
|
---|
659 | 0x02000001, 0xc0080000, 0xa0000000, // mov oPos.w, c0.x
|
---|
660 | 0x02000001, 0xd00f0000, 0x90e40001, // mov oD0, v1
|
---|
661 | 0x0000ffff
|
---|
662 | };
|
---|
663 |
|
---|
664 | static DWORD aPSCode[] =
|
---|
665 | {
|
---|
666 | 0xFFFF0200, // ps_2_0
|
---|
667 | 0x0200001f, 0x80000000, 0x900f0000, // dcl v0
|
---|
668 | 0x02000001, 0x800f0800, 0x90e40000, // mov oC0, v0
|
---|
669 | 0x0000FFFF
|
---|
670 | };
|
---|
671 |
|
---|
672 | static VertexGeometry aVerticesGeometry[] =
|
---|
673 | {
|
---|
674 | { { -0.5f, -0.5f, 0.5f } },
|
---|
675 | { { 0.5f, -0.5f, 0.5f } },
|
---|
676 | { { 0.0f, 0.5f, 0.5f } },
|
---|
677 | };
|
---|
678 |
|
---|
679 | static VertexInstance aVerticesInstance[] =
|
---|
680 | {
|
---|
681 | { D3DCOLOR_XRGB( 0, 0, 255), -0.5f },
|
---|
682 | { D3DCOLOR_XRGB( 0, 255, 0), 0.0f },
|
---|
683 | { D3DCOLOR_XRGB(255, 0, 0), 0.5f },
|
---|
684 | };
|
---|
685 |
|
---|
686 | static USHORT aIndices[] =
|
---|
687 | {
|
---|
688 | 0, 1, 2
|
---|
689 | };
|
---|
690 |
|
---|
691 | HRESULT hr = S_OK;
|
---|
692 |
|
---|
693 | HTEST(pDevice->CreateVertexDeclaration(VertexElements, &mpVertexDecl));
|
---|
694 |
|
---|
695 | HTEST(pDevice->CreateVertexBuffer(sizeof(aVerticesGeometry),
|
---|
696 | 0, /* D3DUSAGE_* */
|
---|
697 | 0, /* FVF */
|
---|
698 | D3DPOOL_DEFAULT,
|
---|
699 | &mpVBGeometry,
|
---|
700 | 0));
|
---|
701 | HTEST(pDevice->CreateVertexBuffer(sizeof(aVerticesInstance),
|
---|
702 | 0, /* D3DUSAGE_* */
|
---|
703 | 0, /* FVF */
|
---|
704 | D3DPOOL_DEFAULT,
|
---|
705 | &mpVBInstance,
|
---|
706 | 0));
|
---|
707 |
|
---|
708 | HTEST(pDevice->CreateIndexBuffer(sizeof(aIndices),
|
---|
709 | 0, /* D3DUSAGE_* */
|
---|
710 | D3DFMT_INDEX16,
|
---|
711 | D3DPOOL_DEFAULT,
|
---|
712 | &mpIB,
|
---|
713 | 0));
|
---|
714 |
|
---|
715 | HTEST(pDevice->CreateVertexShader(aVSCode, &mpVS));
|
---|
716 | HTEST(pDevice->CreatePixelShader(aPSCode, &mpPS));
|
---|
717 |
|
---|
718 | HTEST(d3dCopyToVertexBuffer(mpVBGeometry, aVerticesGeometry, sizeof(aVerticesGeometry)));
|
---|
719 | HTEST(d3dCopyToVertexBuffer(mpVBInstance, aVerticesInstance, sizeof(aVerticesInstance)));
|
---|
720 | HTEST(d3dCopyToIndexBuffer(mpIB, aIndices, sizeof(aIndices)));
|
---|
721 |
|
---|
722 | return hr;
|
---|
723 | }
|
---|
724 |
|
---|
725 | HRESULT D3D9RenderInstance::DoRender(D3D9DeviceProvider *pDP)
|
---|
726 | {
|
---|
727 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
728 |
|
---|
729 | HRESULT hr = S_OK;
|
---|
730 |
|
---|
731 | HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffafafaf, 1.0f, 0));
|
---|
732 |
|
---|
733 | HTEST(pDevice->BeginScene());
|
---|
734 |
|
---|
735 | HTEST(pDevice->SetStreamSource(0, mpVBGeometry, 0, sizeof(VertexGeometry)));
|
---|
736 | /* Draw 2 instances, which should produce a solid blue triangle and a green one. */
|
---|
737 | HTEST(pDevice->SetStreamSourceFreq(0, D3DSTREAMSOURCE_INDEXEDDATA | 2U));
|
---|
738 |
|
---|
739 | HTEST(pDevice->SetStreamSource(1, mpVBInstance, 0, sizeof(VertexInstance)));
|
---|
740 | HTEST(pDevice->SetStreamSourceFreq(1, D3DSTREAMSOURCE_INSTANCEDATA | 1U));
|
---|
741 |
|
---|
742 | HTEST(pDevice->SetVertexDeclaration(mpVertexDecl));
|
---|
743 | HTEST(pDevice->SetVertexShader(mpVS));
|
---|
744 | HTEST(pDevice->SetPixelShader(mpPS));
|
---|
745 | HTEST(pDevice->SetIndices(mpIB));
|
---|
746 | HTEST(pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
|
---|
747 |
|
---|
748 | HTEST(pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
|
---|
749 | 0, /* BaseVertexIndex */
|
---|
750 | 0, /* MinIndex */
|
---|
751 | 3, /* NumVertices */
|
---|
752 | 0, /* StartIndex */
|
---|
753 | 1)); /* PrimitiveCount */
|
---|
754 |
|
---|
755 | HTEST(pDevice->SetStreamSourceFreq(0, 1));
|
---|
756 | HTEST(pDevice->SetStreamSourceFreq(1, 1));
|
---|
757 |
|
---|
758 | HTEST(pDevice->EndScene());
|
---|
759 |
|
---|
760 | HTEST(pDevice->Present(0, 0, 0, 0));
|
---|
761 | return S_OK;
|
---|
762 | }
|
---|
763 |
|
---|
764 |
|
---|
765 | /*
|
---|
766 | * Solid triangles with different Z positions.
|
---|
767 | */
|
---|
768 |
|
---|
769 | class D3D9RenderDepth: public D3D9Render
|
---|
770 | {
|
---|
771 | public:
|
---|
772 | D3D9RenderDepth();
|
---|
773 | virtual ~D3D9RenderDepth();
|
---|
774 | virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
|
---|
775 | virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
|
---|
776 | private:
|
---|
777 | IDirect3DVertexBuffer9 *mpVB;
|
---|
778 | IDirect3DVertexDeclaration9 *mpVertexDecl;
|
---|
779 | IDirect3DVertexShader9 *mpVS;
|
---|
780 | IDirect3DPixelShader9 *mpPS;
|
---|
781 |
|
---|
782 | D3DCamera mCamera;
|
---|
783 |
|
---|
784 | struct Vertex
|
---|
785 | {
|
---|
786 | D3DVECTOR position;
|
---|
787 | };
|
---|
788 | static D3DVERTEXELEMENT9 VertexElements[];
|
---|
789 | };
|
---|
790 |
|
---|
791 | D3DVERTEXELEMENT9 D3D9RenderDepth::VertexElements[] =
|
---|
792 | {
|
---|
793 | {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
|
---|
794 | D3DDECL_END()
|
---|
795 | };
|
---|
796 |
|
---|
797 |
|
---|
798 | D3D9RenderDepth::D3D9RenderDepth()
|
---|
799 | :
|
---|
800 | mpVB(0),
|
---|
801 | mpVertexDecl(0),
|
---|
802 | mpVS(0),
|
---|
803 | mpPS(0)
|
---|
804 | {
|
---|
805 | }
|
---|
806 |
|
---|
807 | D3D9RenderDepth::~D3D9RenderDepth()
|
---|
808 | {
|
---|
809 | D3D_RELEASE(mpVS);
|
---|
810 | D3D_RELEASE(mpPS);
|
---|
811 | D3D_RELEASE(mpVB);
|
---|
812 | D3D_RELEASE(mpVertexDecl);
|
---|
813 | }
|
---|
814 |
|
---|
815 | HRESULT D3D9RenderDepth::InitRender(D3D9DeviceProvider *pDP)
|
---|
816 | {
|
---|
817 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
818 |
|
---|
819 | static DWORD aVSCode[] =
|
---|
820 | {
|
---|
821 | 0xfffe0200, // vs_2_0
|
---|
822 | 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c5, 1, 0, 0, 0
|
---|
823 | 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0
|
---|
824 | 0x04000004, 0x800f0000, 0x90240000, 0xa0400005, 0xa0150005, // mad r0, v0.xyzx, c5.xxxy, c5.yyyx
|
---|
825 | 0x03000009, 0xc0010000, 0x80e40000, 0xa0e40000, // dp4 oPos.x, r0, c0
|
---|
826 | 0x03000009, 0xc0020000, 0x80e40000, 0xa0e40001, // dp4 oPos.y, r0, c1
|
---|
827 | 0x03000009, 0xc0040000, 0x80e40000, 0xa0e40002, // dp4 oPos.z, r0, c2
|
---|
828 | 0x03000009, 0xc0080000, 0x80e40000, 0xa0e40003, // dp4 oPos.w, r0, c3
|
---|
829 | 0x02000001, 0xd00f0000, 0xa0e40004, // mov oD0, c4
|
---|
830 | 0x0000ffff
|
---|
831 | };
|
---|
832 |
|
---|
833 | static DWORD aPSCode[] =
|
---|
834 | {
|
---|
835 | 0xFFFF0200, // ps_2_0
|
---|
836 | 0x0200001f, 0x80000000, 0x900f0000, // dcl v0
|
---|
837 | 0x02000001, 0x800f0800, 0x90e40000, // mov oC0, v0
|
---|
838 | 0x0000FFFF
|
---|
839 | };
|
---|
840 |
|
---|
841 | static Vertex aVertices[] =
|
---|
842 | {
|
---|
843 | { { -1.0f, -1.0f, 0.0f } },
|
---|
844 | { { 1.0f, -1.0f, 0.0f } },
|
---|
845 | { { 0.0f, 1.0f, 0.0f } },
|
---|
846 | };
|
---|
847 |
|
---|
848 | HRESULT hr = S_OK;
|
---|
849 |
|
---|
850 | HTEST(pDevice->CreateVertexDeclaration(VertexElements, &mpVertexDecl));
|
---|
851 | HTEST(pDevice->CreateVertexBuffer(sizeof(aVertices),
|
---|
852 | 0, /* D3DUSAGE_* */
|
---|
853 | 0, /* FVF */
|
---|
854 | D3DPOOL_DEFAULT,
|
---|
855 | &mpVB,
|
---|
856 | 0));
|
---|
857 | HTEST(pDevice->CreateVertexShader(aVSCode, &mpVS));
|
---|
858 | HTEST(pDevice->CreatePixelShader(aPSCode, &mpPS));
|
---|
859 |
|
---|
860 | HTEST(d3dCopyToVertexBuffer(mpVB, aVertices, sizeof(aVertices)));
|
---|
861 |
|
---|
862 | const D3DVECTOR cameraPosition = { 0.0f, 0.0f, -10.0f };
|
---|
863 | const D3DVECTOR cameraAt = { 0.0f, 0.0f, 1.0f };
|
---|
864 | const D3DVECTOR cameraUp = { 0.0f, 1.0f, 0.0f };
|
---|
865 | mCamera.SetupAt(&cameraPosition, &cameraAt, &cameraUp);
|
---|
866 |
|
---|
867 | float w = 800;
|
---|
868 | float h = 600;
|
---|
869 | mCamera.SetProjection(3.14f * 0.5f, w/h, 1.0f, 100.0f);
|
---|
870 |
|
---|
871 | return hr;
|
---|
872 | }
|
---|
873 |
|
---|
874 | static void d3d9RenderDepthDrawTriangle(IDirect3DDevice9 *pDevice, D3DCamera *pCamera,
|
---|
875 | float s, float x, float y, float z, D3DCOLOR color)
|
---|
876 | {
|
---|
877 | HRESULT hr; /* Used by HTEST. */
|
---|
878 |
|
---|
879 | /* Calc world matrix. */
|
---|
880 | D3DMATRIX mtxST;
|
---|
881 | d3dMatrixScaleTranslation(&mtxST, s, x, y, z);
|
---|
882 |
|
---|
883 | D3DMATRIX WVP;
|
---|
884 | d3dMatrixMultiply(&WVP, &mtxST, pCamera->ViewProjection());
|
---|
885 |
|
---|
886 | /* Transpose, because shader will multiply vector row by matrix column,
|
---|
887 | * i.e. columns must be in the shader constants.
|
---|
888 | */
|
---|
889 | d3dMatrixTranspose(&WVP);
|
---|
890 |
|
---|
891 | HTEST(pDevice->SetVertexShaderConstantF(0, &WVP.m[0][0], 4));
|
---|
892 |
|
---|
893 | /* Set color of the triangle. */
|
---|
894 | float aColor[4];
|
---|
895 | aColor[0] = 1.0f * (float)((color >> 16) & 0xff) / 255.0f;
|
---|
896 | aColor[1] = 1.0f * (float)((color >> 8) & 0xff) / 255.0f;
|
---|
897 | aColor[2] = 1.0f * (float)((color ) & 0xff) / 255.0f;
|
---|
898 | aColor[3] = 1.0f;
|
---|
899 | HTEST(pDevice->SetVertexShaderConstantF(4, &aColor[0], 1));
|
---|
900 |
|
---|
901 | HTEST(pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1));
|
---|
902 | }
|
---|
903 |
|
---|
904 | HRESULT D3D9RenderDepth::DoRender(D3D9DeviceProvider *pDP)
|
---|
905 | {
|
---|
906 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
907 |
|
---|
908 | HRESULT hr;
|
---|
909 |
|
---|
910 | HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff7f7f7f, 1.0f, 0));
|
---|
911 |
|
---|
912 | D3DVIEWPORT9 viewport;
|
---|
913 | HTEST(pDevice->GetViewport(&viewport));
|
---|
914 |
|
---|
915 | HTEST(pDevice->SetVertexShader(mpVS));
|
---|
916 | HTEST(pDevice->SetPixelShader(mpPS));
|
---|
917 |
|
---|
918 | HTEST(pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
|
---|
919 | HTEST(pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE));
|
---|
920 |
|
---|
921 | HTEST(pDevice->SetVertexDeclaration(mpVertexDecl));
|
---|
922 | HTEST(pDevice->SetStreamSource(0, mpVB, 0, 3 * sizeof(float)));
|
---|
923 |
|
---|
924 | HTEST(pDevice->BeginScene());
|
---|
925 |
|
---|
926 | viewport.MinZ = 0.2f;
|
---|
927 | viewport.MaxZ = 0.3f;
|
---|
928 | HTEST(pDevice->SetViewport(&viewport));
|
---|
929 |
|
---|
930 | d3d9RenderDepthDrawTriangle(pDevice, &mCamera, 20.0f, -50.0f, -20.0f, 50.0f, D3DCOLOR_XRGB(0, 128, 0));
|
---|
931 | d3d9RenderDepthDrawTriangle(pDevice, &mCamera, 20.0f, -40.0f, -10.0f, 55.0f, D3DCOLOR_XRGB(0, 0, 128));
|
---|
932 |
|
---|
933 | viewport.MinZ = 0.9f;
|
---|
934 | viewport.MaxZ = 1.0f;
|
---|
935 | HTEST(pDevice->SetViewport(&viewport));
|
---|
936 |
|
---|
937 | d3d9RenderDepthDrawTriangle(pDevice, &mCamera, 20.0f, -50.0f, 0.0f, 40.0f, D3DCOLOR_XRGB(0, 255, 0));
|
---|
938 | d3d9RenderDepthDrawTriangle(pDevice, &mCamera, 20.0f, -45.0f, 0.0f, 45.0f, D3DCOLOR_XRGB(0, 0, 255));
|
---|
939 |
|
---|
940 | HTEST(pDevice->EndScene());
|
---|
941 |
|
---|
942 | HTEST(pDevice->Present(0, 0, 0, 0));
|
---|
943 |
|
---|
944 | return S_OK;
|
---|
945 | }
|
---|
946 |
|
---|
947 |
|
---|
948 | /*
|
---|
949 | * Shared resource and render to texture.
|
---|
950 | */
|
---|
951 |
|
---|
952 | class D3D9RenderShared: public D3D9Render
|
---|
953 | {
|
---|
954 | public:
|
---|
955 | D3D9RenderShared();
|
---|
956 | virtual ~D3D9RenderShared();
|
---|
957 | virtual int RequiredDeviceCount() { return 2; }
|
---|
958 | virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
|
---|
959 | virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
|
---|
960 | private:
|
---|
961 | IDirect3DVertexBuffer9 *mpVB;
|
---|
962 | IDirect3DVertexDeclaration9 *mpVertexDecl;
|
---|
963 | IDirect3DVertexShader9 *mpVS;
|
---|
964 | IDirect3DPixelShader9 *mpPS;
|
---|
965 | IDirect3DTexture9 *mpRT;
|
---|
966 | IDirect3DTexture9 *mpTexShared;
|
---|
967 |
|
---|
968 | HANDLE mhRtShared;
|
---|
969 | DWORD mdwRtWidth;
|
---|
970 | DWORD mdwRtHeight;
|
---|
971 |
|
---|
972 | struct Vertex
|
---|
973 | {
|
---|
974 | D3DVECTOR position;
|
---|
975 | D3DCOLOR color;
|
---|
976 | };
|
---|
977 | static D3DVERTEXELEMENT9 VertexElements[];
|
---|
978 |
|
---|
979 | void renderToTexture(IDirect3DDevice9 *pDevice, IDirect3DTexture9 *pTexture);
|
---|
980 | };
|
---|
981 |
|
---|
982 | D3DVERTEXELEMENT9 D3D9RenderShared::VertexElements[] =
|
---|
983 | {
|
---|
984 | {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
|
---|
985 | {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
|
---|
986 | D3DDECL_END()
|
---|
987 | };
|
---|
988 |
|
---|
989 |
|
---|
990 | D3D9RenderShared::D3D9RenderShared()
|
---|
991 | :
|
---|
992 | mpVB(0),
|
---|
993 | mpVertexDecl(0),
|
---|
994 | mpVS(0),
|
---|
995 | mpPS(0),
|
---|
996 | mpRT(0),
|
---|
997 | mpTexShared(0)
|
---|
998 | {
|
---|
999 | mdwRtWidth = 640;
|
---|
1000 | mdwRtHeight = 480;
|
---|
1001 | }
|
---|
1002 |
|
---|
1003 | D3D9RenderShared::~D3D9RenderShared()
|
---|
1004 | {
|
---|
1005 | D3D_RELEASE(mpVS);
|
---|
1006 | D3D_RELEASE(mpPS);
|
---|
1007 | D3D_RELEASE(mpVB);
|
---|
1008 | D3D_RELEASE(mpVertexDecl);
|
---|
1009 | D3D_RELEASE(mpTexShared);
|
---|
1010 | D3D_RELEASE(mpRT);
|
---|
1011 | }
|
---|
1012 |
|
---|
1013 | HRESULT D3D9RenderShared::InitRender(D3D9DeviceProvider *pDP)
|
---|
1014 | {
|
---|
1015 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
1016 |
|
---|
1017 | static DWORD aVSCode[] =
|
---|
1018 | {
|
---|
1019 | 0xFFFE0200, // vs_2_0
|
---|
1020 | 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c0, 1, 0, 0, 0
|
---|
1021 | 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0
|
---|
1022 | 0x0200001f, 0x8000000a, 0x900f0001, // dcl_color v1
|
---|
1023 | 0x02000001, 0xc0070000, 0x90e40000, // mov oPos.xyz, v0
|
---|
1024 | 0x02000001, 0xc0080000, 0xa0000000, // mov oPos.w, c0.x
|
---|
1025 | 0x02000001, 0xd00f0000, 0x90e40001, // mov oD0, v1
|
---|
1026 | 0x0000FFFF
|
---|
1027 | };
|
---|
1028 |
|
---|
1029 | static DWORD aPSCode[] =
|
---|
1030 | {
|
---|
1031 | 0xFFFF0200, // ps_2_0
|
---|
1032 | 0x0200001f, 0x80000000, 0x900f0000, // dcl v0
|
---|
1033 | 0x02000001, 0x800f0800, 0x90e40000, // mov oC0, v0
|
---|
1034 | 0x0000FFFF
|
---|
1035 | };
|
---|
1036 |
|
---|
1037 | static Vertex aVertices[] =
|
---|
1038 | {
|
---|
1039 | { { -0.5f, -0.5f, 0.5f }, D3DCOLOR_XRGB( 0, 0, 255), },
|
---|
1040 | { { 0.5f, -0.5f, 0.5f }, D3DCOLOR_XRGB( 0, 255, 0), },
|
---|
1041 | { { 0.0f, 0.5f, 0.5f }, D3DCOLOR_XRGB(255, 0, 0), },
|
---|
1042 | };
|
---|
1043 |
|
---|
1044 | HRESULT hr = S_OK;
|
---|
1045 |
|
---|
1046 | HTEST(pDevice->CreateVertexDeclaration(VertexElements, &mpVertexDecl));
|
---|
1047 | HTEST(pDevice->CreateVertexBuffer(sizeof(aVertices),
|
---|
1048 | 0, /* D3DUSAGE_* */
|
---|
1049 | 0, /* FVF */
|
---|
1050 | D3DPOOL_DEFAULT,
|
---|
1051 | &mpVB,
|
---|
1052 | 0));
|
---|
1053 | HTEST(pDevice->CreateVertexShader(aVSCode, &mpVS));
|
---|
1054 | HTEST(pDevice->CreatePixelShader(aPSCode, &mpPS));
|
---|
1055 |
|
---|
1056 | HTEST(d3dCopyToVertexBuffer(mpVB, aVertices, sizeof(aVertices)));
|
---|
1057 |
|
---|
1058 | mhRtShared = 0;
|
---|
1059 | HTEST(pDevice->CreateTexture(mdwRtWidth,
|
---|
1060 | mdwRtHeight,
|
---|
1061 | 1,
|
---|
1062 | D3DUSAGE_RENDERTARGET,
|
---|
1063 | D3DFMT_X8R8G8B8,
|
---|
1064 | D3DPOOL_DEFAULT,
|
---|
1065 | &mpRT,
|
---|
1066 | &mhRtShared));
|
---|
1067 |
|
---|
1068 | return hr;
|
---|
1069 | }
|
---|
1070 |
|
---|
1071 | void D3D9RenderShared::renderToTexture(IDirect3DDevice9 *pDevice, IDirect3DTexture9 *pTexture)
|
---|
1072 | {
|
---|
1073 | HRESULT hr = S_OK;
|
---|
1074 |
|
---|
1075 | /*
|
---|
1076 | * Render to texture.
|
---|
1077 | */
|
---|
1078 | IDirect3DSurface9 *pSavedRT = NULL;
|
---|
1079 | HTEST(pDevice->GetRenderTarget(0, &pSavedRT));
|
---|
1080 |
|
---|
1081 | IDirect3DSurface9 *pSurface = NULL;
|
---|
1082 | HTEST(pTexture->GetSurfaceLevel(0, &pSurface));
|
---|
1083 | HTEST(pDevice->SetRenderTarget(0, pSurface));
|
---|
1084 |
|
---|
1085 | HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffafafaf, 1.0f, 0));
|
---|
1086 |
|
---|
1087 | HTEST(pDevice->BeginScene());
|
---|
1088 |
|
---|
1089 | HTEST(pDevice->SetStreamSource(0, mpVB, 0, sizeof(Vertex)));
|
---|
1090 | HTEST(pDevice->SetVertexDeclaration(mpVertexDecl));
|
---|
1091 | HTEST(pDevice->SetVertexShader(mpVS));
|
---|
1092 | HTEST(pDevice->SetPixelShader(mpPS));
|
---|
1093 | HTEST(pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
|
---|
1094 |
|
---|
1095 | HTEST(pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1));
|
---|
1096 |
|
---|
1097 | HTEST(pDevice->EndScene());
|
---|
1098 |
|
---|
1099 | HTEST(pDevice->SetRenderTarget(0, pSavedRT));
|
---|
1100 |
|
---|
1101 | D3D_RELEASE(pSurface);
|
---|
1102 | }
|
---|
1103 |
|
---|
1104 | static void issueQuery(IDirect3DDevice9 *pDevice)
|
---|
1105 | {
|
---|
1106 | HRESULT hr;
|
---|
1107 |
|
---|
1108 | IDirect3DQuery9 *pQuery;
|
---|
1109 | hr = pDevice->CreateQuery(D3DQUERYTYPE_EVENT, &pQuery);
|
---|
1110 | if (hr == D3D_OK)
|
---|
1111 | {
|
---|
1112 | hr = pQuery->Issue(D3DISSUE_END);
|
---|
1113 | if (hr == D3D_OK)
|
---|
1114 | {
|
---|
1115 | do
|
---|
1116 | {
|
---|
1117 | hr = pQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
|
---|
1118 | } while (hr == S_FALSE);
|
---|
1119 | }
|
---|
1120 |
|
---|
1121 | D3D_RELEASE(pQuery);
|
---|
1122 | }
|
---|
1123 | }
|
---|
1124 |
|
---|
1125 | HRESULT D3D9RenderShared::DoRender(D3D9DeviceProvider *pDP)
|
---|
1126 | {
|
---|
1127 | HRESULT hr = S_OK;
|
---|
1128 |
|
---|
1129 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
1130 |
|
---|
1131 | renderToTexture(pDevice, mpRT);
|
---|
1132 |
|
---|
1133 | issueQuery(pDevice);
|
---|
1134 |
|
---|
1135 | IDirect3DDevice9 *pDevice2 = pDP->Device(1);
|
---|
1136 | if (pDevice2)
|
---|
1137 | {
|
---|
1138 | HTEST(pDevice2->CreateTexture(mdwRtWidth,
|
---|
1139 | mdwRtHeight,
|
---|
1140 | 1,
|
---|
1141 | D3DUSAGE_RENDERTARGET,
|
---|
1142 | D3DFMT_X8R8G8B8,
|
---|
1143 | D3DPOOL_DEFAULT,
|
---|
1144 | &mpTexShared,
|
---|
1145 | &mhRtShared));
|
---|
1146 |
|
---|
1147 | drawTexture(pDevice2, mpTexShared, 50, 50, 200, 200);
|
---|
1148 | HTEST(pDevice2->Present(0, 0, 0, 0));
|
---|
1149 | }
|
---|
1150 | else
|
---|
1151 | {
|
---|
1152 | drawTexture(pDevice, mpRT, 50, 50, 200, 200);
|
---|
1153 | HTEST(pDevice->Present(0, 0, 0, 0));
|
---|
1154 | }
|
---|
1155 |
|
---|
1156 | return S_OK;
|
---|
1157 | }
|
---|
1158 |
|
---|
1159 |
|
---|
1160 | /*
|
---|
1161 | * Use ColorFill to clear a part of the backbuffer.
|
---|
1162 | */
|
---|
1163 |
|
---|
1164 | class D3D9RenderColorFill: public D3D9Render
|
---|
1165 | {
|
---|
1166 | public:
|
---|
1167 | D3D9RenderColorFill() {}
|
---|
1168 | virtual ~D3D9RenderColorFill() {}
|
---|
1169 | virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
|
---|
1170 | virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
|
---|
1171 | };
|
---|
1172 |
|
---|
1173 | HRESULT D3D9RenderColorFill::InitRender(D3D9DeviceProvider *pDP)
|
---|
1174 | {
|
---|
1175 | (void)pDP;
|
---|
1176 | return S_OK;
|
---|
1177 | }
|
---|
1178 |
|
---|
1179 | HRESULT D3D9RenderColorFill::DoRender(D3D9DeviceProvider *pDP)
|
---|
1180 | {
|
---|
1181 | HRESULT hr = S_OK;
|
---|
1182 |
|
---|
1183 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
1184 |
|
---|
1185 | pDevice->Clear(0, 0, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
|
---|
1186 |
|
---|
1187 | IDirect3DSurface9 *pBackBuffer = NULL;
|
---|
1188 | HTEST(pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer));
|
---|
1189 |
|
---|
1190 | RECT rDst;
|
---|
1191 | rDst.left = 50;
|
---|
1192 | rDst.top = 10;
|
---|
1193 | rDst.right = 250;
|
---|
1194 | rDst.bottom = 250;
|
---|
1195 |
|
---|
1196 | HTEST(pDevice->ColorFill(pBackBuffer, &rDst, D3DCOLOR_XRGB(0, 255, 0)));
|
---|
1197 |
|
---|
1198 | D3D_RELEASE(pBackBuffer);
|
---|
1199 |
|
---|
1200 | HTEST(pDevice->Present(0, 0, 0, 0));
|
---|
1201 | return S_OK;
|
---|
1202 | }
|
---|
1203 |
|
---|
1204 |
|
---|
1205 | /*
|
---|
1206 | * Render a texture to texture.
|
---|
1207 | */
|
---|
1208 |
|
---|
1209 | class D3D9RenderTexture: public D3D9Render
|
---|
1210 | {
|
---|
1211 | public:
|
---|
1212 | D3D9RenderTexture();
|
---|
1213 | virtual ~D3D9RenderTexture();
|
---|
1214 | virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
|
---|
1215 | virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
|
---|
1216 | private:
|
---|
1217 | IDirect3DVertexBuffer9 *mpVB;
|
---|
1218 | IDirect3DVertexDeclaration9 *mpVertexDecl;
|
---|
1219 | IDirect3DVertexShader9 *mpVS;
|
---|
1220 | IDirect3DPixelShader9 *mpPS;
|
---|
1221 | IDirect3DTexture9 *mpTexDst;
|
---|
1222 | IDirect3DTexture9 *mpTexSrc;
|
---|
1223 |
|
---|
1224 | static const int cxTexture = 8;
|
---|
1225 | static const int cyTexture = 8;
|
---|
1226 |
|
---|
1227 | struct Vertex
|
---|
1228 | {
|
---|
1229 | D3DVECTOR position;
|
---|
1230 | float x, y;
|
---|
1231 | };
|
---|
1232 | static D3DVERTEXELEMENT9 VertexElements[];
|
---|
1233 |
|
---|
1234 | void renderToTexture(IDirect3DDevice9 *pDevice, IDirect3DTexture9 *pTexture, IDirect3DTexture9 *pTexSrc);
|
---|
1235 | };
|
---|
1236 |
|
---|
1237 | D3DVERTEXELEMENT9 D3D9RenderTexture::VertexElements[] =
|
---|
1238 | {
|
---|
1239 | {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
|
---|
1240 | {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
|
---|
1241 | D3DDECL_END()
|
---|
1242 | };
|
---|
1243 |
|
---|
1244 |
|
---|
1245 | D3D9RenderTexture::D3D9RenderTexture()
|
---|
1246 | :
|
---|
1247 | mpVB(0),
|
---|
1248 | mpVertexDecl(0),
|
---|
1249 | mpVS(0),
|
---|
1250 | mpPS(0),
|
---|
1251 | mpTexDst(0),
|
---|
1252 | mpTexSrc(0)
|
---|
1253 | {
|
---|
1254 | }
|
---|
1255 |
|
---|
1256 | D3D9RenderTexture::~D3D9RenderTexture()
|
---|
1257 | {
|
---|
1258 | D3D_RELEASE(mpVS);
|
---|
1259 | D3D_RELEASE(mpPS);
|
---|
1260 | D3D_RELEASE(mpVB);
|
---|
1261 | D3D_RELEASE(mpVertexDecl);
|
---|
1262 | D3D_RELEASE(mpTexSrc);
|
---|
1263 | D3D_RELEASE(mpTexDst);
|
---|
1264 | }
|
---|
1265 |
|
---|
1266 | HRESULT D3D9RenderTexture::InitRender(D3D9DeviceProvider *pDP)
|
---|
1267 | {
|
---|
1268 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
1269 |
|
---|
1270 | static DWORD aVSCode[] =
|
---|
1271 | {
|
---|
1272 | 0xFFFE0200, // vs_2_0
|
---|
1273 | 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c0, 1, 0, 0, 0
|
---|
1274 | 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0
|
---|
1275 | 0x0200001f, 0x80000005, 0x900f0001, // dcl_texcoord v1
|
---|
1276 | 0x02000001, 0xc0070000, 0x90e40000, // mov oPos.xyz, v0
|
---|
1277 | 0x02000001, 0xc0080000, 0xa0000000, // mov oPos.w, c0.x
|
---|
1278 | 0x02000001, 0xe0030000, 0x90e40001, // mov oT0.xy, v1
|
---|
1279 | 0x0000FFFF
|
---|
1280 | };
|
---|
1281 |
|
---|
1282 | static DWORD aVSCodeMad[] =
|
---|
1283 | {
|
---|
1284 | 0xFFFE0200, // vs_2_0
|
---|
1285 | 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c0, 1, 0, 0, 0
|
---|
1286 | 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0
|
---|
1287 | 0x0200001f, 0x80000005, 0x900f0001, // dcl_texcoord v1
|
---|
1288 | 0x04000004, 0xc00f0000, 0x90240000, 0xa0400000, 0xa0150000, // mad oPos, v0.xyzx, c0.xxxy, c0.yyyx
|
---|
1289 | 0x02000001, 0xe0030000, 0x90e40001, // mov oT0.xy, v1
|
---|
1290 | 0x0000FFFF
|
---|
1291 | };
|
---|
1292 |
|
---|
1293 | static DWORD aPSCodeSwap[] =
|
---|
1294 | {
|
---|
1295 | 0xffff0200, // ps_2_0
|
---|
1296 | 0x0200001f, 0x80000000, 0xb0030000, // dcl t0.xy
|
---|
1297 | 0x0200001f, 0x90000000, 0xa00f0800, // dcl_2d s0
|
---|
1298 | 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, // texld r0, t0, s0
|
---|
1299 | 0x02000001, 0x80090001, 0x80d20000, // mov r1.xw, r0.zxyw
|
---|
1300 | 0x02000001, 0x80040001, 0x80000000, // mov r1.z, r0.x
|
---|
1301 | 0x02000001, 0x80020001, 0x80550000, // mov r1.y, r0.y
|
---|
1302 | 0x02000001, 0x800f0800, 0x80e40001, // mov oC0, r1
|
---|
1303 | 0x0000ffff
|
---|
1304 | };
|
---|
1305 |
|
---|
1306 | static DWORD aPSCodePass[] =
|
---|
1307 | {
|
---|
1308 | 0xffff0200, // ps_2_0
|
---|
1309 | 0x0200001f, 0x80000000, 0xb0030000, // dcl t0.xy
|
---|
1310 | 0x0200001f, 0x90000000, 0xa00f0800, // dcl_2d s0
|
---|
1311 | 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, // texld r0, t0, s0
|
---|
1312 | 0x02000001, 0x800f0800, 0x80e40000, // mov oC0, r0
|
---|
1313 | 0x0000ffff
|
---|
1314 | };
|
---|
1315 |
|
---|
1316 | static DWORD aPSCodeCoord[] =
|
---|
1317 | {
|
---|
1318 | 0xffff0200, // ps_2_0
|
---|
1319 | 0x0200001f, 0x80000000, 0xb0010000, // dcl t0.x
|
---|
1320 | 0x02000001, 0x800f0000, 0xb0000000, // mov r0, t0.x
|
---|
1321 | 0x02000001, 0x800f0800, 0x80e40000, // mov oC0, r0
|
---|
1322 | 0x0000ffff
|
---|
1323 | };
|
---|
1324 |
|
---|
1325 | static Vertex aVertices[] =
|
---|
1326 | {
|
---|
1327 | { { -1.0f, -1.0f, 0.0f }, 0.0f, 1.0f},
|
---|
1328 | { { 1.0f, -1.0f, 0.0f }, 1.0f, 1.0f},
|
---|
1329 | { { -1.0f, 1.0f, 0.0f }, 0.0f, 0.0f},
|
---|
1330 |
|
---|
1331 | { { -1.0f, 1.0f, 0.0f }, 0.0f, 0.0f},
|
---|
1332 | { { 1.0f, -1.0f, 0.0f }, 1.0f, 1.0f},
|
---|
1333 | { { 1.0f, 1.0f, 0.0f }, 1.0f, 0.0f},
|
---|
1334 | };
|
---|
1335 |
|
---|
1336 | HRESULT hr = S_OK;
|
---|
1337 |
|
---|
1338 | HTEST(pDevice->CreateVertexDeclaration(VertexElements, &mpVertexDecl));
|
---|
1339 | HTEST(pDevice->CreateVertexBuffer(sizeof(aVertices),
|
---|
1340 | 0, /* D3DUSAGE_* */
|
---|
1341 | 0, /* FVF */
|
---|
1342 | D3DPOOL_DEFAULT,
|
---|
1343 | &mpVB,
|
---|
1344 | 0));
|
---|
1345 | HTEST(pDevice->CreateVertexShader(aVSCodeMad, &mpVS));
|
---|
1346 | HTEST(pDevice->CreatePixelShader(aPSCodeSwap, &mpPS));
|
---|
1347 |
|
---|
1348 | HTEST(d3dCopyToVertexBuffer(mpVB, aVertices, sizeof(aVertices)));
|
---|
1349 |
|
---|
1350 | HTEST(pDevice->CreateTexture(cxTexture,
|
---|
1351 | cyTexture,
|
---|
1352 | 1,
|
---|
1353 | D3DUSAGE_RENDERTARGET,
|
---|
1354 | D3DFMT_A8R8G8B8,
|
---|
1355 | D3DPOOL_DEFAULT,
|
---|
1356 | &mpTexDst,
|
---|
1357 | NULL));
|
---|
1358 |
|
---|
1359 | HTEST(pDevice->CreateTexture(cxTexture,
|
---|
1360 | cyTexture,
|
---|
1361 | 1,
|
---|
1362 | D3DUSAGE_DYNAMIC,
|
---|
1363 | D3DFMT_A8R8G8B8,
|
---|
1364 | D3DPOOL_DEFAULT,
|
---|
1365 | &mpTexSrc,
|
---|
1366 | NULL));
|
---|
1367 |
|
---|
1368 | D3DLOCKED_RECT LockedRect;
|
---|
1369 | HTEST(mpTexSrc->LockRect(0, &LockedRect, NULL /* entire texture */, 0));
|
---|
1370 |
|
---|
1371 | unsigned char *pScanline = (unsigned char *)LockedRect.pBits;
|
---|
1372 | for (UINT y = 0; y < cxTexture; ++y)
|
---|
1373 | {
|
---|
1374 | for (UINT x = 0; x < cxTexture; ++x)
|
---|
1375 | {
|
---|
1376 | if (x < y)
|
---|
1377 | {
|
---|
1378 | pScanline[x * 4 + 0] = 0xff;
|
---|
1379 | pScanline[x * 4 + 1] = 0x00;
|
---|
1380 | pScanline[x * 4 + 2] = 0x00;
|
---|
1381 | pScanline[x * 4 + 3] = 0x00;
|
---|
1382 | }
|
---|
1383 | else
|
---|
1384 | {
|
---|
1385 | pScanline[x * 4 + 0] = 0x00;
|
---|
1386 | pScanline[x * 4 + 1] = 0x00;
|
---|
1387 | pScanline[x * 4 + 2] = 0xff;
|
---|
1388 | pScanline[x * 4 + 3] = 0x00;
|
---|
1389 | }
|
---|
1390 | }
|
---|
1391 |
|
---|
1392 | pScanline += LockedRect.Pitch;
|
---|
1393 | }
|
---|
1394 |
|
---|
1395 | HTEST(mpTexSrc->UnlockRect(0));
|
---|
1396 |
|
---|
1397 | return hr;
|
---|
1398 | }
|
---|
1399 |
|
---|
1400 | void D3D9RenderTexture::renderToTexture(IDirect3DDevice9 *pDevice, IDirect3DTexture9 *pTexture, IDirect3DTexture9 *pTexSrc)
|
---|
1401 | {
|
---|
1402 | HRESULT hr = S_OK;
|
---|
1403 |
|
---|
1404 | /*
|
---|
1405 | * Render to texture.
|
---|
1406 | */
|
---|
1407 | IDirect3DSurface9 *pSavedRT = NULL;
|
---|
1408 | HTEST(pDevice->GetRenderTarget(0, &pSavedRT));
|
---|
1409 |
|
---|
1410 | IDirect3DSurface9 *pSurface = NULL;
|
---|
1411 | HTEST(pTexture->GetSurfaceLevel(0, &pSurface));
|
---|
1412 | HTEST(pDevice->SetRenderTarget(0, pSurface));
|
---|
1413 |
|
---|
1414 | HTEST(pDevice->BeginScene());
|
---|
1415 |
|
---|
1416 | HTEST(pDevice->SetStreamSource(0, mpVB, 0, sizeof(Vertex)));
|
---|
1417 | HTEST(pDevice->SetVertexDeclaration(mpVertexDecl));
|
---|
1418 | HTEST(pDevice->SetVertexShader(mpVS));
|
---|
1419 | HTEST(pDevice->SetPixelShader(mpPS));
|
---|
1420 | HTEST(pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
|
---|
1421 | HTEST(pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE));
|
---|
1422 |
|
---|
1423 | HTEST(pDevice->SetTexture(0, pTexSrc));
|
---|
1424 |
|
---|
1425 | HTEST(pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2));
|
---|
1426 |
|
---|
1427 | HTEST(pDevice->EndScene());
|
---|
1428 |
|
---|
1429 | HTEST(pDevice->SetRenderTarget(0, pSavedRT));
|
---|
1430 |
|
---|
1431 | D3D_RELEASE(pSurface);
|
---|
1432 | }
|
---|
1433 |
|
---|
1434 | HRESULT D3D9RenderTexture::DoRender(D3D9DeviceProvider *pDP)
|
---|
1435 | {
|
---|
1436 | HRESULT hr = S_OK;
|
---|
1437 |
|
---|
1438 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
1439 |
|
---|
1440 | renderToTexture(pDevice, mpTexDst, mpTexSrc);
|
---|
1441 |
|
---|
1442 | drawTexture(pDevice, mpTexDst, 50, 50, 200, 200);
|
---|
1443 |
|
---|
1444 | HTEST(pDevice->Present(0, 0, 0, 0));
|
---|
1445 |
|
---|
1446 | return S_OK;
|
---|
1447 | }
|
---|
1448 |
|
---|
1449 |
|
---|
1450 | /*
|
---|
1451 | * Render a texture to screen.
|
---|
1452 | */
|
---|
1453 |
|
---|
1454 | class D3D9RenderTextureToScreen: public D3D9Render
|
---|
1455 | {
|
---|
1456 | public:
|
---|
1457 | D3D9RenderTextureToScreen(float cPixelShift);
|
---|
1458 | virtual ~D3D9RenderTextureToScreen();
|
---|
1459 | virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
|
---|
1460 | virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
|
---|
1461 | private:
|
---|
1462 | IDirect3DVertexBuffer9 *mpVB;
|
---|
1463 | IDirect3DVertexDeclaration9 *mpVertexDecl;
|
---|
1464 | IDirect3DVertexShader9 *mpVS;
|
---|
1465 | IDirect3DPixelShader9 *mpPS;
|
---|
1466 | IDirect3DTexture9 *mpTex;
|
---|
1467 |
|
---|
1468 | static const int cxTexture = 4;
|
---|
1469 | static const int cyTexture = 4;
|
---|
1470 | float mcPixelShift;
|
---|
1471 |
|
---|
1472 | struct Vertex
|
---|
1473 | {
|
---|
1474 | D3DVECTOR position;
|
---|
1475 | float x, y;
|
---|
1476 | };
|
---|
1477 | static D3DVERTEXELEMENT9 VertexElements[];
|
---|
1478 | static DWORD adwTextureData[cxTexture * cyTexture];
|
---|
1479 | };
|
---|
1480 |
|
---|
1481 | D3DVERTEXELEMENT9 D3D9RenderTextureToScreen::VertexElements[] =
|
---|
1482 | {
|
---|
1483 | {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
|
---|
1484 | {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
|
---|
1485 | D3DDECL_END()
|
---|
1486 | };
|
---|
1487 |
|
---|
1488 | DWORD D3D9RenderTextureToScreen::adwTextureData[cxTexture * cyTexture] =
|
---|
1489 | {
|
---|
1490 | 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00FFFFFF,
|
---|
1491 | 0x0000FF00, 0x00FF0000, 0x000000FF, 0x00FFFFFF,
|
---|
1492 | 0x00FF0000, 0x000000FF, 0x0000FF00, 0x00FFFFFF,
|
---|
1493 | 0x0000FFFF, 0x00FF00FF, 0x00FFFF00, 0x00FFFFFF,
|
---|
1494 | };
|
---|
1495 |
|
---|
1496 |
|
---|
1497 | D3D9RenderTextureToScreen::D3D9RenderTextureToScreen(float cPixelShift)
|
---|
1498 | :
|
---|
1499 | mpVB(0),
|
---|
1500 | mpVertexDecl(0),
|
---|
1501 | mpVS(0),
|
---|
1502 | mpPS(0),
|
---|
1503 | mpTex(0),
|
---|
1504 | mcPixelShift(cPixelShift)
|
---|
1505 | {
|
---|
1506 | }
|
---|
1507 |
|
---|
1508 | D3D9RenderTextureToScreen::~D3D9RenderTextureToScreen()
|
---|
1509 | {
|
---|
1510 | D3D_RELEASE(mpVS);
|
---|
1511 | D3D_RELEASE(mpPS);
|
---|
1512 | D3D_RELEASE(mpVB);
|
---|
1513 | D3D_RELEASE(mpVertexDecl);
|
---|
1514 | D3D_RELEASE(mpTex);
|
---|
1515 | }
|
---|
1516 |
|
---|
1517 | HRESULT D3D9RenderTextureToScreen::InitRender(D3D9DeviceProvider *pDP)
|
---|
1518 | {
|
---|
1519 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
1520 |
|
---|
1521 | static DWORD aVSCode[] =
|
---|
1522 | {
|
---|
1523 | 0xFFFE0200, // vs_2_0
|
---|
1524 | 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c0, 1, 0, 0, 0
|
---|
1525 | 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0
|
---|
1526 | 0x0200001f, 0x80000005, 0x900f0001, // dcl_texcoord v1
|
---|
1527 | 0x02000001, 0xc0070000, 0x90e40000, // mov oPos.xyz, v0
|
---|
1528 | 0x02000001, 0xc0080000, 0xa0000000, // mov oPos.w, c0.x
|
---|
1529 | 0x02000001, 0xe0030000, 0x90e40001, // mov oT0.xy, v1
|
---|
1530 | 0x0000FFFF
|
---|
1531 | };
|
---|
1532 |
|
---|
1533 | static DWORD aPSCodePass[] =
|
---|
1534 | {
|
---|
1535 | 0xffff0200, // ps_2_0
|
---|
1536 | 0x0200001f, 0x80000000, 0xb0030000, // dcl t0.xy
|
---|
1537 | 0x0200001f, 0x90000000, 0xa00f0800, // dcl_2d s0
|
---|
1538 | 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, // texld r0, t0, s0
|
---|
1539 | 0x02000001, 0x800f0800, 0x80e40000, // mov oC0, r0
|
---|
1540 | 0x0000ffff
|
---|
1541 | };
|
---|
1542 |
|
---|
1543 | static DWORD aPSCodeCoord[] =
|
---|
1544 | {
|
---|
1545 | 0xffff0200, // ps_2_0
|
---|
1546 | 0x0200001f, 0x80000000, 0xb0010000, // dcl t0.x
|
---|
1547 | 0x02000001, 0x800f0000, 0xb0000000, // mov r0, t0.x
|
---|
1548 | 0x02000001, 0x800f0800, 0x80e40000, // mov oC0, r0
|
---|
1549 | 0x0000ffff
|
---|
1550 | };
|
---|
1551 |
|
---|
1552 | D3DVIEWPORT9 vp;
|
---|
1553 | pDevice->GetViewport(&vp);
|
---|
1554 |
|
---|
1555 | int x1 = 1;
|
---|
1556 | int y1 = 1;
|
---|
1557 | int x2 = x1 + cxTexture * 1;
|
---|
1558 | int y2 = y1 + cyTexture * 1;
|
---|
1559 |
|
---|
1560 | float cPixelShift = mcPixelShift;
|
---|
1561 |
|
---|
1562 | #define VX(x) ( 2.0f * (float(x) + cPixelShift) / float(vp.Width) - 1.0f)
|
---|
1563 | #define VY(y) (-2.0f * (float(y) + cPixelShift) / float(vp.Height) + 1.0f)
|
---|
1564 |
|
---|
1565 | Vertex vTopLeft = { { VX(x1), VY(y1), 0.0f }, 0.0f, 0.0f};
|
---|
1566 | Vertex vBottomLeft = { { VX(x1), VY(y2), 0.0f }, 0.0f, 1.0f};
|
---|
1567 | Vertex vTopRight = { { VX(x2), VY(y1), 0.0f }, 1.0f, 0.0f};
|
---|
1568 | Vertex vBottomRight = { { VX(x2), VY(y2), 0.0f }, 1.0f, 1.0f};
|
---|
1569 |
|
---|
1570 | Vertex aVertices[6] =
|
---|
1571 | {
|
---|
1572 | vBottomLeft, vBottomRight, vTopLeft,
|
---|
1573 | vTopLeft, vBottomRight, vTopRight
|
---|
1574 | };
|
---|
1575 |
|
---|
1576 | HRESULT hr = S_OK;
|
---|
1577 |
|
---|
1578 | HTEST(pDevice->CreateVertexDeclaration(VertexElements, &mpVertexDecl));
|
---|
1579 | HTEST(pDevice->CreateVertexBuffer(sizeof(aVertices),
|
---|
1580 | 0, /* D3DUSAGE_* */
|
---|
1581 | 0, /* FVF */
|
---|
1582 | D3DPOOL_DEFAULT,
|
---|
1583 | &mpVB,
|
---|
1584 | 0));
|
---|
1585 | HTEST(pDevice->CreateVertexShader(aVSCode, &mpVS));
|
---|
1586 | HTEST(pDevice->CreatePixelShader(aPSCodePass, &mpPS));
|
---|
1587 |
|
---|
1588 | HTEST(d3dCopyToVertexBuffer(mpVB, aVertices, sizeof(aVertices)));
|
---|
1589 |
|
---|
1590 | HTEST(pDevice->CreateTexture(cxTexture,
|
---|
1591 | cyTexture,
|
---|
1592 | 1,
|
---|
1593 | D3DUSAGE_DYNAMIC,
|
---|
1594 | D3DFMT_A8R8G8B8,
|
---|
1595 | D3DPOOL_DEFAULT,
|
---|
1596 | &mpTex,
|
---|
1597 | NULL));
|
---|
1598 |
|
---|
1599 | D3DLOCKED_RECT LockedRect;
|
---|
1600 | HTEST(mpTex->LockRect(0, &LockedRect, NULL /* entire texture */, D3DLOCK_DISCARD));
|
---|
1601 |
|
---|
1602 | unsigned char *pu8Dst = (unsigned char *)LockedRect.pBits;
|
---|
1603 | for (int y = 0; y < cyTexture; ++y)
|
---|
1604 | {
|
---|
1605 | memcpy(pu8Dst, &adwTextureData[y * cxTexture], 4 * cxTexture);
|
---|
1606 | pu8Dst += LockedRect.Pitch;
|
---|
1607 | }
|
---|
1608 |
|
---|
1609 | HTEST(mpTex->UnlockRect(0));
|
---|
1610 |
|
---|
1611 | return hr;
|
---|
1612 | }
|
---|
1613 |
|
---|
1614 | HRESULT D3D9RenderTextureToScreen::DoRender(D3D9DeviceProvider *pDP)
|
---|
1615 | {
|
---|
1616 | HRESULT hr = S_OK;
|
---|
1617 |
|
---|
1618 | IDirect3DDevice9 *pDevice = pDP->Device(0);
|
---|
1619 |
|
---|
1620 | HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff7f7f7f, 1.0f, 0));
|
---|
1621 |
|
---|
1622 | HTEST(pDevice->BeginScene());
|
---|
1623 |
|
---|
1624 | HTEST(pDevice->SetStreamSource(0, mpVB, 0, sizeof(Vertex)));
|
---|
1625 | HTEST(pDevice->SetVertexDeclaration(mpVertexDecl));
|
---|
1626 | HTEST(pDevice->SetVertexShader(mpVS));
|
---|
1627 | HTEST(pDevice->SetPixelShader(mpPS));
|
---|
1628 | HTEST(pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
|
---|
1629 | HTEST(pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE));
|
---|
1630 |
|
---|
1631 | HTEST(pDevice->SetTexture(0, mpTex));
|
---|
1632 | HTEST(pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR));
|
---|
1633 | HTEST(pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR));
|
---|
1634 | HTEST(pDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR));
|
---|
1635 |
|
---|
1636 | HTEST(pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2));
|
---|
1637 |
|
---|
1638 | HTEST(pDevice->EndScene());
|
---|
1639 |
|
---|
1640 | HTEST(pDevice->Present(0, 0, 0, 0));
|
---|
1641 |
|
---|
1642 | return S_OK;
|
---|
1643 | }
|
---|
1644 |
|
---|
1645 |
|
---|
1646 | /*
|
---|
1647 | * "Public" interface.
|
---|
1648 | */
|
---|
1649 |
|
---|
1650 | D3D9Render *CreateRender(int iRenderId)
|
---|
1651 | {
|
---|
1652 | switch (iRenderId)
|
---|
1653 | {
|
---|
1654 | case 11:
|
---|
1655 | return new D3D9RenderTextureToScreen(0.0f);
|
---|
1656 | case 10:
|
---|
1657 | return new D3D9RenderTextureToScreen(-0.5f);
|
---|
1658 | case 9:
|
---|
1659 | return new D3D9RenderTexture();
|
---|
1660 | case 8:
|
---|
1661 | return new D3D9RenderColorFill();
|
---|
1662 | case 7:
|
---|
1663 | return new D3D9RenderShared();
|
---|
1664 | case 6:
|
---|
1665 | return new D3D9RenderDepth();
|
---|
1666 | case 5:
|
---|
1667 | return new D3D9RenderInstance();
|
---|
1668 | case 4:
|
---|
1669 | return new D3D9RenderCubeMap();
|
---|
1670 | case 3:
|
---|
1671 | return new D3D9RenderTriangleShader();
|
---|
1672 | case 2:
|
---|
1673 | return new D3D9RenderTriangleFVF();
|
---|
1674 | case 1:
|
---|
1675 | return new D3D9RenderTriangle();
|
---|
1676 | case 0:
|
---|
1677 | return new D3D9RenderClear();
|
---|
1678 | default:
|
---|
1679 | break;
|
---|
1680 | }
|
---|
1681 | return 0;
|
---|
1682 | }
|
---|
1683 |
|
---|
1684 | void DeleteRender(D3D9Render *pRender)
|
---|
1685 | {
|
---|
1686 | delete pRender;
|
---|
1687 | }
|
---|