Paul Gofman : d3dx9: Implement light and material effect states application.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Mar 4 09:48:33 CST 2016


Module: wine
Branch: master
Commit: 6df87a66472a0f86c5e61455a584b734d5f368ed
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6df87a66472a0f86c5e61455a584b734d5f368ed

Author: Paul Gofman <gofmanp at gmail.com>
Date:   Thu Mar  3 15:22:11 2016 +0300

d3dx9: Implement light and material effect states application.

Signed-off-by: Paul Gofman <gofmanp at gmail.com>
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/d3dx9_36/effect.c       | 143 +++++++++++++++++++++++++++++++++++++++++++
 dlls/d3dx9_36/tests/effect.c |   8 +--
 2 files changed, 147 insertions(+), 4 deletions(-)

diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index b14c8bb..bf39ce2 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -2515,6 +2515,116 @@ static HRESULT d3dx9_get_param_value_ptr(struct ID3DXEffectImpl *effect, struct
     return E_NOTIMPL;
 }
 
+static void d3dx9_set_light_parameter(enum LIGHT_TYPE op, D3DLIGHT9 *light, void *value)
+{
+    static const struct
+    {
+        unsigned int offset;
+        const char *name;
+    }
+    light_tbl[] =
+    {
+       {FIELD_OFFSET(D3DLIGHT9, Type),         "LC_TYPE"},
+       {FIELD_OFFSET(D3DLIGHT9, Diffuse),      "LT_DIFFUSE"},
+       {FIELD_OFFSET(D3DLIGHT9, Specular),     "LT_SPECULAR"},
+       {FIELD_OFFSET(D3DLIGHT9, Ambient),      "LT_AMBIENT"},
+       {FIELD_OFFSET(D3DLIGHT9, Position),     "LT_POSITION"},
+       {FIELD_OFFSET(D3DLIGHT9, Direction),    "LT_DIRECTION"},
+       {FIELD_OFFSET(D3DLIGHT9, Range),        "LT_RANGE"},
+       {FIELD_OFFSET(D3DLIGHT9, Falloff),      "LT_FALLOFF"},
+       {FIELD_OFFSET(D3DLIGHT9, Attenuation0), "LT_ATTENUATION0"},
+       {FIELD_OFFSET(D3DLIGHT9, Attenuation1), "LT_ATTENUATION1"},
+       {FIELD_OFFSET(D3DLIGHT9, Attenuation2), "LT_ATTENUATION2"},
+       {FIELD_OFFSET(D3DLIGHT9, Theta),        "LT_THETA"},
+       {FIELD_OFFSET(D3DLIGHT9, Phi),          "LT_PHI"}
+    };
+    switch (op)
+    {
+        case LT_TYPE:
+            TRACE("LT_TYPE %u.\n", *(D3DLIGHTTYPE *)value);
+            light->Type = *(D3DLIGHTTYPE *)value;
+            break;
+        case LT_DIFFUSE:
+        case LT_SPECULAR:
+        case LT_AMBIENT:
+        {
+            D3DCOLORVALUE c = *(D3DCOLORVALUE *)value;
+
+            TRACE("%s (%f %f %f %f).\n", light_tbl[op].name, c.r, c.g, c.b, c.a);
+            *(D3DCOLORVALUE *)((char *)light + light_tbl[op].offset) = c;
+            break;
+        }
+        case LT_POSITION:
+        case LT_DIRECTION:
+        {
+            D3DVECTOR v = *(D3DVECTOR *)value;
+
+            TRACE("%s (%f %f %f).\n", light_tbl[op].name, v.x, v.y, v.z);
+            *(D3DVECTOR *)((char *)light + light_tbl[op].offset) = v;
+            break;
+        }
+        case LT_RANGE:
+        case LT_FALLOFF:
+        case LT_ATTENUATION0:
+        case LT_ATTENUATION1:
+        case LT_ATTENUATION2:
+        case LT_THETA:
+        case LT_PHI:
+        {
+            float v = *(float *)value;
+            TRACE("%s %f.\n", light_tbl[op].name, v);
+            *(float *)((char *)light + light_tbl[op].offset) = v;
+            break;
+        }
+        default:
+            WARN("Unknown light parameter %u.\n", op);
+            break;
+    }
+}
+
+static void d3dx9_set_material_parameter(enum MATERIAL_TYPE op, D3DMATERIAL9 *material, void *value)
+{
+    static const struct
+    {
+        unsigned int offset;
+        const char *name;
+    }
+    material_tbl[] =
+    {
+       {FIELD_OFFSET(D3DMATERIAL9, Diffuse),  "MT_DIFFUSE"},
+       {FIELD_OFFSET(D3DMATERIAL9, Ambient),  "MT_AMBIENT"},
+       {FIELD_OFFSET(D3DMATERIAL9, Specular), "MT_SPECULAR"},
+       {FIELD_OFFSET(D3DMATERIAL9, Emissive), "MT_EMISSIVE"},
+       {FIELD_OFFSET(D3DMATERIAL9, Power),    "MT_POWER"}
+    };
+
+    switch (op)
+    {
+        case MT_POWER:
+        {
+            float v = *(float *)value;
+
+            TRACE("%s %f.\n", material_tbl[op].name, v);
+            material->Power = v;
+            break;
+        }
+        case MT_DIFFUSE:
+        case MT_AMBIENT:
+        case MT_SPECULAR:
+        case MT_EMISSIVE:
+        {
+            D3DCOLORVALUE c = *(D3DCOLORVALUE *)value;
+
+            TRACE("%s, value (%f %f %f %f).\n", material_tbl[op].name, c.r, c.g, c.b, c.a);
+            *(D3DCOLORVALUE *)((char *)material + material_tbl[op].offset) = c;
+            break;
+        }
+        default:
+            WARN("Unknown material parameter %u.\n", op);
+            break;
+    }
+}
+
 static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass, struct d3dx_state *state)
 {
     IDirect3DDevice9 *device = effect->device;
@@ -2558,6 +2668,39 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
             TRACE("%s, state %u.\n", state_table[state->operation].name, state->index);
             return IDirect3DDevice9_SetTransform(device, state_table[state->operation].op + state->index,
                     (D3DMATRIX *)param_value);
+        case SC_LIGHTENABLE:
+            TRACE("%s, index %u, value %u.\n", state_table[state->operation].name, state->index, *(BOOL *)param_value);
+            return IDirect3DDevice9_LightEnable(device, state->index, *(BOOL *)param_value);
+        case SC_LIGHT:
+        {
+            D3DLIGHT9 light;
+
+            TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
+                    state_table[state->operation].op);
+            hr = IDirect3DDevice9_GetLight(device, state->index, &light);
+            if (FAILED(hr))
+            {
+                WARN("Could not get light, hr %#x.\n", hr);
+                memset(&light, 0, sizeof(light));
+            }
+            d3dx9_set_light_parameter(state_table[state->operation].op, &light, param_value);
+            return IDirect3DDevice9_SetLight(device, state->index, &light);
+        }
+        case SC_MATERIAL:
+        {
+            D3DMATERIAL9 material;
+
+            TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
+                    state_table[state->operation].op);
+            hr = IDirect3DDevice9_GetMaterial(device, &material);
+            if (FAILED(hr))
+            {
+                WARN("Could not get material, hr %#x.\n", hr);
+                memset(&material, 0, sizeof(material));
+            }
+            d3dx9_set_material_parameter(state_table[state->operation].op, &material, param_value);
+            return IDirect3DDevice9_SetMaterial(device, &material);
+        }
         case SC_NPATCHMODE:
             TRACE("%s, nsegments %f.\n", state_table[state->operation].name, *(float *)param_value);
             return IDirect3DDevice9_SetNPatchMode(device, *(float *)param_value);
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c
index 81a7d12..3bcba72 100644
--- a/dlls/d3dx9_36/tests/effect.c
+++ b/dlls/d3dx9_36/tests/effect.c
@@ -2910,11 +2910,11 @@ static void test_effect_states(IDirect3DDevice9 *device)
     }
 
     hr = IDirect3DDevice9_GetLightEnable(device, 2, &bval);
-    todo_wine ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+    ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
     if (hr == D3D_OK)
         ok(bval, "Got result %u, expected TRUE.\n", bval);
     hr = IDirect3DDevice9_GetLight(device, 2, &light);
-    todo_wine ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+    ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
     if (hr == D3D_OK)
         ok(light.Position.x == 4.0f && light.Position.y == 5.0f && light.Position.z == 6.0f,
                 "Got unexpected light position (%f, %f, %f).\n", light.Position.x, light.Position.y, light.Position.z);
@@ -2950,9 +2950,9 @@ static void test_effect_states(IDirect3DDevice9 *device)
     todo_wine ok(!memcmp(mat.m, test_mat.m, sizeof(mat)), "World matrix not restored.\n");
 
     hr = IDirect3DDevice9_GetLightEnable(device, 2, &bval);
-    todo_wine ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+    ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
     if (hr == D3D_OK)
-        ok(!bval, "Got result %u, expected 0.\n", bval);
+        todo_wine ok(!bval, "Got result %u, expected 0.\n", bval);
 
     if (effect)
         effect->lpVtbl->Release(effect);




More information about the wine-cvs mailing list