[v3 3/7] d3dx9: implement light and material effect states application.
Paul Gofman
gofmanp at gmail.com
Thu Mar 3 06:22:11 CST 2016
Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
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);
--
2.5.0
More information about the wine-patches
mailing list