Module: wine Branch: master Commit: 6df87a66472a0f86c5e61455a584b734d5f368ed URL: http://source.winehq.org/git/wine.git/?a=commit;h=6df87a66472a0f86c5e61455a5...
Author: Paul Gofman gofmanp@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@gmail.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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);