Module: wine Branch: master Commit: c957f8a921154c293f1dda53595f45a396477d1f URL: http://source.winehq.org/git/wine.git/?a=commit;h=c957f8a921154c293f1dda5359...
Author: Nozomi Kodama Nozomi.Kodama@yahoo.com Date: Sun Jul 15 10:18:50 2012 +0200
d3dx9_36: Implementation of D3DXSHEvalDirection.
---
dlls/d3dx9_36/d3dx9_36.spec | 2 +- dlls/d3dx9_36/math.c | 60 +++++++++++++++++++++++++++++++++++++++++++ dlls/d3dx9_36/tests/math.c | 37 ++++++++++++++++++++++++++ include/d3dx9math.h | 1 + 4 files changed, 99 insertions(+), 1 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec index 9230d55..b59c8a9 100644 --- a/dlls/d3dx9_36/d3dx9_36.spec +++ b/dlls/d3dx9_36/d3dx9_36.spec @@ -275,7 +275,7 @@ @ stdcall D3DXSHAdd(ptr long ptr ptr) @ stdcall D3DXSHDot(long ptr ptr) @ stub D3DXSHEvalConeLight(long ptr long long long long ptr ptr ptr) -@ stub D3DXSHEvalDirection(ptr long ptr) +@ stdcall D3DXSHEvalDirection(ptr long ptr) @ stub D3DXSHEvalDirectionalLight(long ptr long long long long ptr ptr ptr) @ stub D3DXSHEvalHemisphereLight(long ptr long long ptr ptr ptr) @ stub D3DXSHEvalSphericalLight(long ptr long long long long ptr ptr ptr) diff --git a/dlls/d3dx9_36/math.c b/dlls/d3dx9_36/math.c index 79a0bca..89a19af 100644 --- a/dlls/d3dx9_36/math.c +++ b/dlls/d3dx9_36/math.c @@ -1995,6 +1995,66 @@ FLOAT WINAPI D3DXSHDot(UINT order, CONST FLOAT *a, CONST FLOAT *b) return s; }
+FLOAT* WINAPI D3DXSHEvalDirection(FLOAT *out, UINT order, CONST D3DXVECTOR3 *dir) +{ + + TRACE("(%p, %u, %p)\n", out, order, dir); + + if ( (order < D3DXSH_MINORDER) || (order > D3DXSH_MAXORDER) ) + return out; + + out[0] = 0.5f / sqrt(D3DX_PI); + out[1] = -0.5f / sqrt(D3DX_PI / 3.0f) * dir->y; + out[2] = 0.5f / sqrt(D3DX_PI / 3.0f) * dir->z; + out[3] = -0.5f / sqrt(D3DX_PI / 3.0f) * dir->x; + if ( order == 2 ) + return out; + + out[4] = 0.5f / sqrt(D3DX_PI / 15.0f) * dir->x * dir->y; + out[5] = -0.5f / sqrt(D3DX_PI / 15.0f) * dir->y * dir->z; + out[6] = 0.25f / sqrt(D3DX_PI / 5.0f) * ( 3.0f * dir->z * dir->z - 1.0f ); + out[7] = -0.5f / sqrt(D3DX_PI / 15.0f) * dir->x * dir->z; + out[8] = 0.25f / sqrt(D3DX_PI / 15.0f) * ( dir->x * dir->x - dir->y * dir->y ); + if ( order == 3 ) + return out; + + out[9] = -sqrt(70.0f / D3DX_PI) / 8.0f * dir->y * (3.0f * dir->x * dir->x - dir->y * dir->y ); + out[10] = sqrt(105.0f / D3DX_PI) / 2.0f * dir->x * dir->y * dir->z; + out[11] = -sqrt(42.0 / D3DX_PI) / 8.0f * dir->y * ( -1.0f + 5.0f * dir->z * dir->z ); + out[12] = sqrt(7.0f / D3DX_PI) / 4.0f * dir->z * ( 5.0f * dir->z * dir->z - 3.0f ); + out[13] = sqrt(42.0 / D3DX_PI) / 8.0f * dir->x * ( 1.0f - 5.0f * dir->z * dir->z ); + out[14] = sqrt(105.0f / D3DX_PI) / 4.0f * dir->z * ( dir->x * dir->x - dir->y * dir->y ); + out[15] = -sqrt(70.0f / D3DX_PI) / 8.0f * dir->x * ( dir->x * dir->x - 3.0f * dir->y * dir->y ); + if ( order == 4 ) + return out; + + out[16] = 0.75f * sqrt(35.0f / D3DX_PI) * dir->x * dir->y * (dir->x * dir->x - dir->y * dir->y ); + out[17] = 3.0f * dir->z * out[9]; + out[18] = 0.75f * sqrt(5.0f / D3DX_PI) * dir->x * dir->y * ( 7.0f * dir->z * dir->z - 1.0f ); + out[19] = 0.375f * sqrt(10.0f / D3DX_PI) * dir->y * dir->z * ( 3.0f - 7.0f * dir->z * dir->z ); + out[20] = 3.0f / ( 16.0f * sqrt(D3DX_PI) ) * ( 35.0f * dir->z * dir->z * dir->z * dir->z - 30.f * dir->z * dir->z + 3.0f ); + out[21] = 0.375f * sqrt(10.0f / D3DX_PI) * dir->x * dir->z * ( 3.0f - 7.0f * dir->z * dir->z ); + out[22] = 0.375f * sqrt(5.0f / D3DX_PI) * ( dir->x * dir->x - dir->y * dir->y ) * ( 7.0f * dir->z * dir->z - 1.0f); + out[23] = 3.0 * dir->z * out[15]; + out[24] = 3.0f / 16.0f * sqrt(35.0f / D3DX_PI) * ( dir->x * dir->x * dir->x * dir->x- 6.0f * dir->x * dir->x * dir->y * dir->y + dir->y * dir->y * dir->y * dir->y ); + if ( order == 5 ) + return out; + + out[25] = -3.0f/ 32.0f * sqrt(154.0f / D3DX_PI) * dir->y * ( 5.0f * dir->x * dir->x * dir->x * dir->x - 10.0f * dir->x * dir->x * dir->y * dir->y + dir->y * dir->y * dir->y * dir->y ); + out[26] = 0.75f * sqrt(385.0f / D3DX_PI) * dir->x * dir->y * dir->z * ( dir->x * dir->x - dir->y * dir->y ); + out[27] = sqrt(770.0f / D3DX_PI) / 32.0f * dir->y * ( 3.0f * dir->x * dir->x - dir->y * dir->y ) * ( 1.0f - 9.0f * dir->z * dir->z ); + out[28] = sqrt(1155.0f / D3DX_PI) / 4.0f * dir->x * dir->y * dir->z * ( 3.0f * dir->z * dir->z - 1.0f); + out[29] = sqrt(165.0f / D3DX_PI) / 16.0f * dir->y * ( 14.0f * dir->z * dir->z - 21.0f * dir->z * dir->z * dir->z * dir->z - 1.0f ); + out[30] = sqrt(11.0f / D3DX_PI) / 16.0f * dir->z * ( 63.0f * dir->z * dir->z * dir->z * dir->z - 70.0f * dir->z * dir->z + 15.0f ); + out[31] = sqrt(165.0f / D3DX_PI) / 16.0f * dir->x * ( 14.0f * dir->z * dir->z - 21.0f * dir->z * dir->z * dir->z * dir->z - 1.0f ); + out[32] = sqrt(1155.0f / D3DX_PI) / 8.0f * dir->z * ( dir->x * dir->x - dir->y * dir->y ) * ( 3.0f * dir->z * dir->z - 1.0f ); + out[33] = sqrt(770.0f / D3DX_PI) / 32.0f * dir->x * ( dir->x * dir->x - 3.0f * dir->y * dir->y ) * ( 1.0f - 9.0f * dir->z * dir->z ); + out[34] = 3.0f / 16.0f * sqrt(385.0f / D3DX_PI) * dir->z * ( dir->x * dir->x * dir->x * dir->x - 6.0 * dir->x * dir->x * dir->y * dir->y + dir->y * dir->y * dir->y * dir->y ); + out[35] = -3.0f/ 32.0f * sqrt(154.0f / D3DX_PI) * dir->x * ( dir->x * dir->x * dir->x * dir->x - 10.0f * dir->x * dir->x * dir->y * dir->y + 5.0f * dir->y * dir->y * dir->y * dir->y ); + + return out; +} + FLOAT* WINAPI D3DXSHMultiply2(FLOAT *out, CONST FLOAT *a, CONST FLOAT *b) { FLOAT ta, tb; diff --git a/dlls/d3dx9_36/tests/math.c b/dlls/d3dx9_36/tests/math.c index 66d4689..fecb413 100644 --- a/dlls/d3dx9_36/tests/math.c +++ b/dlls/d3dx9_36/tests/math.c @@ -2422,6 +2422,42 @@ static void test_D3DXSHDot(void) return; }
+static void test_D3DXSHEvalDirection(void) +{ + unsigned int i, order; + D3DXVECTOR3 d; + FLOAT a[100], expected[100], *received_ptr; + CONST FLOAT table[36] = + { 0.282095f, -0.977205f, 1.465808f, -0.488603f, 2.185097f, -6.555291f, + 8.200181f, -3.277646f, -1.638823f, 1.180087f, 17.343668f, -40.220032f, + 47.020218f, -20.110016f, -13.007751f, 6.490479f, -15.020058f, 10.620785f, + 117.325661f, -240.856750f, 271.657288f, -120.428375f, -87.994247f, 58.414314f, + -4.380850f, 24.942520f, -149.447693f, 78.278130f, 747.791748f, -1427.687866f, + 1574.619141, -713.843933f, -560.843811f, 430.529724, -43.588909, -26.911665, }; + + d.x = 1.0; d.y = 2.0f; d.z = 3.0f; + + for(order = 0; order < 10; order++) + { + for(i = 0; i < 100; i++) + a[i] = 1.5f + i; + + received_ptr = D3DXSHEvalDirection(a, order, &d); + ok(received_ptr == a, "Expected %p, received %p\n", a, received_ptr); + + for(i = 0; i < 100; i++) + { + /* if the order is < D3DXSH_MINORDER or order > D3DXSH_MAXORDER or the index of the element is greater than order * order - 1, D3DXSHEvalDirection does not modify the output */ + if ( (order < D3DXSH_MINORDER) || (order > D3DXSH_MAXORDER) || (i >= order * order) ) + expected[i] = 1.5f + i; + else + expected[i] = table[i]; + + ok(relative_error(a[i], expected[i]) < admitted_error, "order %u, index %u: expected %f, received %f\n", order, i, expected[i], a[i]); + } + } +} + static void test_D3DXSHMultiply2(void) { unsigned int i; @@ -2512,6 +2548,7 @@ START_TEST(math) test_D3DXFloat_Array(); test_D3DXSHAdd(); test_D3DXSHDot(); + test_D3DXSHEvalDirection(); test_D3DXSHMultiply2(); test_D3DXSHMultiply3(); test_D3DXSHScale(); diff --git a/include/d3dx9math.h b/include/d3dx9math.h index ab3e2b0..602c2a4 100644 --- a/include/d3dx9math.h +++ b/include/d3dx9math.h @@ -379,6 +379,7 @@ FLOAT *WINAPI D3DXFloat16To32Array(FLOAT *pout, CONST D3DXFLOAT16 *pin, UINT n);
FLOAT* WINAPI D3DXSHAdd(FLOAT *out, UINT order, CONST FLOAT *a, CONST FLOAT *b); FLOAT WINAPI D3DXSHDot(UINT order, CONST FLOAT *a, CONST FLOAT *b); +FLOAT* WINAPI D3DXSHEvalDirection(FLOAT *out, UINT order, CONST D3DXVECTOR3 *dir); FLOAT* WINAPI D3DXSHMultiply2(FLOAT *out, CONST FLOAT *a, CONST FLOAT *b); FLOAT* WINAPI D3DXSHMultiply3(FLOAT *out, CONST FLOAT *a, CONST FLOAT *b); FLOAT* WINAPI D3DXSHScale(FLOAT *out, UINT order, CONST FLOAT *a, CONST FLOAT scale);