Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/wined3d/utils.c | 25 +++++++++---------------- dlls/wined3d/wined3d_private.h | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 16 deletions(-)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index ef469100fd..fb545cf610 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -6442,23 +6442,16 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, settings->point_size = state->gl_primitive_type == GL_POINTS; settings->per_vertex_point_size = !!(si->use_map & 1u << WINED3D_FFP_PSIZE);
- if (state->render_states[WINED3D_RS_COLORVERTEX]) { - settings->diffuse_source = validate_material_colour_source(si->use_map, - state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE]); - settings->emissive_source = validate_material_colour_source(si->use_map, - state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE]); - settings->ambient_source = validate_material_colour_source(si->use_map, - state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE]); - settings->specular_source = validate_material_colour_source(si->use_map, - state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]); - } - else - { - settings->diffuse_source = WINED3D_MCS_MATERIAL; - settings->emissive_source = WINED3D_MCS_MATERIAL; - settings->ambient_source = WINED3D_MCS_MATERIAL; - settings->specular_source = WINED3D_MCS_MATERIAL; + enum wined3d_material_color_source diffuse_source, emissive_source, + ambient_source, specular_source; + + wined3d_get_mcs(&diffuse_source, &emissive_source, &ambient_source, &specular_source, state, si); + + settings->diffuse_source = diffuse_source; + settings->emissive_source = emissive_source; + settings->ambient_source = ambient_source; + settings->specular_source = specular_source; }
for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 34fa1d3ef3..716f5101c9 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4850,6 +4850,38 @@ static inline enum wined3d_material_color_source validate_material_colour_source return WINED3D_MCS_MATERIAL; }
+static inline void wined3d_get_mcs(enum wined3d_material_color_source *diffuse_source, + enum wined3d_material_color_source *emissive_source, enum wined3d_material_color_source *ambient_source, + enum wined3d_material_color_source *specular_source, const struct wined3d_state *state, + const struct wined3d_stream_info *si) +{ + if (state->render_states[WINED3D_RS_LIGHTING]) + { + if (state->render_states[WINED3D_RS_COLORVERTEX]) + { + *diffuse_source = validate_material_colour_source(si->use_map, + state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE]); + *emissive_source = validate_material_colour_source(si->use_map, + state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE]); + *ambient_source = validate_material_colour_source(si->use_map, + state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE]); + *specular_source = validate_material_colour_source(si->use_map, + state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]); + } + else + { + *diffuse_source = *emissive_source = *ambient_source = + *specular_source = WINED3D_MCS_MATERIAL; + } + } + else + { + *diffuse_source = WINED3D_MCS_COLOR1; + *specular_source = WINED3D_MCS_COLOR2; + *emissive_source = *ambient_source = WINED3D_MCS_MATERIAL; + } +} + BOOL invert_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m) DECLSPEC_HIDDEN;
void compute_normal_matrix(float *normal_matrix, BOOL legacy_lighting,
Signed-off-by: Paul Gofman gofmanp@gmail.com --- v2: - use wined3d_format_convert_from_float() instead of introducing d3dcolor_from_wined3d_color(); - renamed clamp_vec() to wined3d_color_clamp(); - do not assume D3DCOLOR format for input stream color value; - introduced material_specular_state_color variable; v3: - fix missing default color initialiazation in wined3d_format_get_color(); - use wined3d_get_mcs() function.
dlls/wined3d/device.c | 179 +++++++++++++++++++++++++++++++++--------- 1 file changed, 143 insertions(+), 36 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 5a94d03b9b..f1072f9cdb 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3072,20 +3072,143 @@ static unsigned int wined3d_get_flexible_vertex_size(DWORD fvf) return size; }
+static void wined3d_format_get_color(const struct wined3d_format *format, const BYTE *data, + struct wined3d_color *color) +{ + static const struct wined3d_color default_color = {0.0f, 0.0f, 0.0f, 1.0f}; + float *output = &color->r; + unsigned int i; + + switch (format->id) + { + case WINED3DFMT_B8G8R8A8_UNORM: + wined3d_color_from_d3dcolor(color, *(const DWORD *)data); + break; + + case WINED3DFMT_R8G8B8A8_UNORM: + { + DWORD value = *(const DWORD *)data; + + color->r = (value & 0xff) / 255.0f; + color->g = ((value >> 8) & 0xff) / 255.0f; + color->b = ((value >> 16) & 0xff) / 255.0f; + color->a = ((value >> 24) & 0xff) / 255.0f; + break; + } + + case WINED3DFMT_R16G16_UNORM: + case WINED3DFMT_R16G16B16A16_UNORM: + { + const unsigned short *ushort_data = (const unsigned short *)data; + + *color = default_color; + + for (i = 0; i < format->component_count; ++i) + output[i] = ushort_data[i] / 65535.0f; + + break; + } + + case WINED3DFMT_R32_FLOAT: + case WINED3DFMT_R32G32_FLOAT: + case WINED3DFMT_R32G32B32_FLOAT: + case WINED3DFMT_R32G32B32A32_FLOAT: + { + const float *float_data = (const float *)data; + + *color = default_color; + + for (i = 0; i < format->component_count; ++i) + output[i] = float_data[i]; + + break; + } + + default: + { + static BOOL warned; + + *color = default_color; + + if (!warned) + { + FIXME("Unhandled color format conversion, format %s.\n", debug_d3dformat(format->id)); + warned = TRUE; + } + break; + } + } +} + +static void color_from_mcs(struct wined3d_color *color, enum wined3d_material_color_source mcs, + const struct wined3d_color *material_color, unsigned int index, + const struct wined3d_stream_info *stream_info) +{ + const struct wined3d_stream_info_element *element = NULL; + + switch (mcs) + { + case WINED3D_MCS_MATERIAL: + *color = *material_color; + return; + case WINED3D_MCS_COLOR1: + if (!(stream_info->use_map & (1u << WINED3D_FFP_DIFFUSE))) + { + color->r = color->g = color->b = color->a = 1.0f; + return; + } + element = &stream_info->elements[WINED3D_FFP_DIFFUSE]; + break; + case WINED3D_MCS_COLOR2: + if (!(stream_info->use_map & (1u << WINED3D_FFP_SPECULAR))) + { + color->r = color->g = color->b = 0.0f; + color->a = 1.0f; + return; + } + element = &stream_info->elements[WINED3D_FFP_SPECULAR]; + break; + default: + color->r = color->g = color->b = color->a = 0.0f; + ERR("Invalid material color source %#x.\n", mcs); + return; + } + wined3d_format_get_color(element->format, element->data.addr + index * element->stride, color); +} + +static float wined3d_clamp(float value, float min_value, float max_value) +{ + return value < min_value ? min_value : value > max_value ? max_value : value; +} + +static void wined3d_color_clamp(struct wined3d_color *dst, const struct wined3d_color *src, + float min_value, float max_value) +{ + dst->r = wined3d_clamp(src->r, min_value, max_value); + dst->g = wined3d_clamp(src->g, min_value, max_value); + dst->b = wined3d_clamp(src->b, min_value, max_value); + dst->a = wined3d_clamp(src->a, min_value, max_value); +} + /* Context activation is done by the caller. */ #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size) static HRESULT process_vertices_strided(const struct wined3d_device *device, DWORD dwDestIndex, DWORD dwCount, const struct wined3d_stream_info *stream_info, struct wined3d_buffer *dest, DWORD flags, DWORD dst_fvf) { + enum wined3d_material_color_source diffuse_source, specular_source, ambient_source, emissive_source; + const struct wined3d_color *material_specular_state_color; struct wined3d_matrix mat, proj_mat, view_mat, world_mat; + const struct wined3d_state *state = &device->state; + const struct wined3d_format *output_color_format; + static const struct wined3d_color black; struct wined3d_map_desc map_desc; struct wined3d_box box = {0}; struct wined3d_viewport vp; unsigned int vertex_size; + DWORD numTextures; unsigned int i; BYTE *dest_ptr; BOOL doClip; - DWORD numTextures; HRESULT hr;
if (stream_info->use_map & (1u << WINED3D_FFP_NORMAL)) @@ -3095,11 +3218,11 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
if (!(stream_info->use_map & (1u << WINED3D_FFP_POSITION))) { - ERR("Source has no position mask\n"); + ERR("Source has no position mask.\n"); return WINED3DERR_INVALIDCALL; }
- if (device->state.render_states[WINED3D_RS_CLIPPING]) + if (state->render_states[WINED3D_RS_CLIPPING]) { static BOOL warned = FALSE; /* @@ -3161,6 +3284,13 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
numTextures = (dst_fvf & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
+ wined3d_get_mcs(&diffuse_source, &emissive_source, &ambient_source, &specular_source, + state, stream_info); + + output_color_format = wined3d_get_format(device->adapter, WINED3DFMT_B8G8R8A8_UNORM, 0); + material_specular_state_color = state->render_states[WINED3D_RS_SPECULARENABLE] + ? &state->material.specular : &black; + for (i = 0; i < dwCount; i+= 1) { unsigned int tex_index;
@@ -3278,47 +3408,24 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
if (dst_fvf & WINED3DFVF_DIFFUSE) { - const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_DIFFUSE]; - const DWORD *color_d = (const DWORD *)(element->data.addr + i * element->stride); - if (!(stream_info->use_map & (1u << WINED3D_FFP_DIFFUSE))) - { - static BOOL warned = FALSE; + struct wined3d_color material_diffuse;
- if(!warned) { - ERR("No diffuse color in source, but destination has one\n"); - warned = TRUE; - } + color_from_mcs(&material_diffuse, diffuse_source, &state->material.diffuse, i, stream_info);
- *( (DWORD *) dest_ptr) = 0xffffffff; - dest_ptr += sizeof(DWORD); - } - else - { - copy_and_next(dest_ptr, color_d, sizeof(DWORD)); - } + wined3d_color_clamp(&material_diffuse, &material_diffuse, 0.0f, 1.0f); + *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_color_format, &material_diffuse); + dest_ptr += sizeof(DWORD); }
if (dst_fvf & WINED3DFVF_SPECULAR) { - /* What's the color value in the feedback buffer? */ - const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_SPECULAR]; - const DWORD *color_s = (const DWORD *)(element->data.addr + i * element->stride); - if (!(stream_info->use_map & (1u << WINED3D_FFP_SPECULAR))) - { - static BOOL warned = FALSE; + struct wined3d_color material_specular;
- if(!warned) { - ERR("No specular color in source, but destination has one\n"); - warned = TRUE; - } + color_from_mcs(&material_specular, specular_source, material_specular_state_color, i, stream_info);
- *(DWORD *)dest_ptr = 0xff000000; - dest_ptr += sizeof(DWORD); - } - else - { - copy_and_next(dest_ptr, color_s, sizeof(DWORD)); - } + wined3d_color_clamp(&material_specular, &material_specular, 0.0f, 1.0f); + *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_color_format, &material_specular); + dest_ptr += sizeof(DWORD); }
for (tex_index = 0; tex_index < numTextures; ++tex_index)
Signed-off-by: Paul Gofman gofmanp@gmail.com --- v3: - rename multiply_vector_matrix() to wined3d_vec4_mat().
dlls/wined3d/glsl_shader.c | 25 ++++++------------------- dlls/wined3d/wined3d_private.h | 13 +++++++++++++ 2 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index f85fb5a3e1..a977fdf8f9 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1374,19 +1374,6 @@ static void shader_glsl_ffp_vertex_lightambient_uniform(const struct wined3d_con checkGLcall("glUniform3fv"); }
-static void multiply_vector_matrix(struct wined3d_vec4 *dest, const struct wined3d_vec4 *src1, - const struct wined3d_matrix *src2) -{ - struct wined3d_vec4 temp; - - temp.x = (src1->x * src2->_11) + (src1->y * src2->_21) + (src1->z * src2->_31) + (src1->w * src2->_41); - temp.y = (src1->x * src2->_12) + (src1->y * src2->_22) + (src1->z * src2->_32) + (src1->w * src2->_42); - temp.z = (src1->x * src2->_13) + (src1->y * src2->_23) + (src1->z * src2->_33) + (src1->w * src2->_43); - temp.w = (src1->x * src2->_14) + (src1->y * src2->_24) + (src1->z * src2->_34) + (src1->w * src2->_44); - - *dest = temp; -} - static void shader_glsl_ffp_vertex_light_uniform(const struct wined3d_context *context, const struct wined3d_state *state, unsigned int light, const struct wined3d_light_info *light_info, struct glsl_shader_prog_link *prog) @@ -1402,7 +1389,7 @@ static void shader_glsl_ffp_vertex_light_uniform(const struct wined3d_context *c switch (light_info->OriginalParms.type) { case WINED3D_LIGHT_POINT: - multiply_vector_matrix(&vec4, &light_info->position, view); + wined3d_vec4_mat(&vec4, &light_info->position, view); GL_EXTCALL(glUniform4fv(prog->vs.light_location[light].position, 1, &vec4.x)); GL_EXTCALL(glUniform1f(prog->vs.light_location[light].range, light_info->OriginalParms.range)); GL_EXTCALL(glUniform1f(prog->vs.light_location[light].c_att, light_info->OriginalParms.attenuation0)); @@ -1411,10 +1398,10 @@ static void shader_glsl_ffp_vertex_light_uniform(const struct wined3d_context *c break;
case WINED3D_LIGHT_SPOT: - multiply_vector_matrix(&vec4, &light_info->position, view); + wined3d_vec4_mat(&vec4, &light_info->position, view); GL_EXTCALL(glUniform4fv(prog->vs.light_location[light].position, 1, &vec4.x));
- multiply_vector_matrix(&vec4, &light_info->direction, view); + wined3d_vec4_mat(&vec4, &light_info->direction, view); GL_EXTCALL(glUniform3fv(prog->vs.light_location[light].direction, 1, &vec4.x));
GL_EXTCALL(glUniform1f(prog->vs.light_location[light].range, light_info->OriginalParms.range)); @@ -1427,12 +1414,12 @@ static void shader_glsl_ffp_vertex_light_uniform(const struct wined3d_context *c break;
case WINED3D_LIGHT_DIRECTIONAL: - multiply_vector_matrix(&vec4, &light_info->direction, view); + wined3d_vec4_mat(&vec4, &light_info->direction, view); GL_EXTCALL(glUniform3fv(prog->vs.light_location[light].direction, 1, &vec4.x)); break;
case WINED3D_LIGHT_PARALLELPOINT: - multiply_vector_matrix(&vec4, &light_info->position, view); + wined3d_vec4_mat(&vec4, &light_info->position, view); GL_EXTCALL(glUniform4fv(prog->vs.light_location[light].position, 1, &vec4.x)); break;
@@ -1505,7 +1492,7 @@ static void shader_glsl_clip_plane_uniform(const struct wined3d_context *context { invert_matrix(&matrix, &state->transforms[WINED3D_TS_VIEW]); transpose_matrix(&matrix, &matrix); - multiply_vector_matrix(&plane, &plane, &matrix); + wined3d_vec4_mat(&plane, &plane, &matrix); }
GL_EXTCALL(glUniform4fv(prog->vs.clip_planes_location + index, 1, &plane.x)); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 716f5101c9..57f5e69edc 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4882,6 +4882,19 @@ static inline void wined3d_get_mcs(enum wined3d_material_color_source *diffuse_s } }
+static inline void wined3d_vec4_mat(struct wined3d_vec4 *dest, const struct wined3d_vec4 *src1, + const struct wined3d_matrix *src2) +{ + struct wined3d_vec4 temp; + + temp.x = (src1->x * src2->_11) + (src1->y * src2->_21) + (src1->z * src2->_31) + (src1->w * src2->_41); + temp.y = (src1->x * src2->_12) + (src1->y * src2->_22) + (src1->z * src2->_32) + (src1->w * src2->_42); + temp.z = (src1->x * src2->_13) + (src1->y * src2->_23) + (src1->z * src2->_33) + (src1->w * src2->_43); + temp.w = (src1->x * src2->_14) + (src1->y * src2->_24) + (src1->z * src2->_34) + (src1->w * src2->_44); + + *dest = temp; +} + BOOL invert_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m) DECLSPEC_HIDDEN;
void compute_normal_matrix(float *normal_matrix, BOOL legacy_lighting,
Signed-off-by: Paul Gofman gofmanp@gmail.com --- v2: - rename dot_vec3 to wined3d_vec3_dot(); - use wined3d_vec3_dot() in normalize_vec3(); - use functions with explicit types instead of madd_vec(); - rename multiply_vector3_matrix() to multiply_vector3_matrix3(); - introduce 'struct wined3d_matrix3' and use it in multiply_vector3_matrix3(). - increase bit field size for light count. v3: - use wined3d_ prefix for vector math functions; - set .a component to 1.0 for output specular color regardless of _FOGENABLE.
dlls/ddraw/tests/ddraw1.c | 4 +- dlls/wined3d/device.c | 302 ++++++++++++++++++++++++++++++--- dlls/wined3d/wined3d_private.h | 1 + 3 files changed, 283 insertions(+), 24 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 7dda6eba20..9525b2dc0c 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -5894,7 +5894,7 @@ static void test_material(void) ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); color = get_surface_color(rt, 320, 240); if (test_data[i].material) - todo_wine ok(compare_color(color, test_data[i].expected_color, 1) + ok(compare_color(color, test_data[i].expected_color, 1) /* The Windows 8 testbot appears to return undefined results. */ || broken(TRUE), "Got unexpected color 0x%08x, test %u.\n", color, i); @@ -6273,7 +6273,7 @@ static void test_lighting(void) ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240); - todo_wine ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color); + ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color); }
IDirect3DExecuteBuffer_Release(execute_buffer); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index f1072f9cdb..e8835e5548 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3176,6 +3176,11 @@ static void color_from_mcs(struct wined3d_color *color, enum wined3d_material_co wined3d_format_get_color(element->format, element->data.addr + index * element->stride, color); }
+static float wined3d_vec3_dot(const struct wined3d_vec3 *src1, const struct wined3d_vec3 *src2) +{ + return src1->x * src2->x + src1->y * src2->y + src1->z * src2->z; +} + static float wined3d_clamp(float value, float min_value, float max_value) { return value < min_value ? min_value : value > max_value ? max_value : value; @@ -3190,6 +3195,206 @@ static void wined3d_color_clamp(struct wined3d_color *dst, const struct wined3d_ dst->a = wined3d_clamp(src->a, min_value, max_value); }
+static void wined3d_vec3_normalize(struct wined3d_vec3 *dest, const struct wined3d_vec3 *src) +{ + float rnorm = 1.0f / sqrtf(wined3d_vec3_dot(src, src)); + + *dest = *src; + if (isfinite(rnorm)) + { + dest->x *= rnorm; + dest->y *= rnorm; + dest->z *= rnorm; + } +} + +static void wined3d_color_rgb_mul_add(struct wined3d_color *dst, const struct wined3d_color *src, float c) +{ + dst->r += src->r * c; + dst->g += src->g * c; + dst->b += src->b * c; +} + +struct wined3d_matrix3 +{ + float _11, _12, _13; + float _21, _22, _23; + float _31, _32, _33; +}; + +static void wined3d_vec3_m3x3(struct wined3d_vec3 *dest, const struct wined3d_vec3 *src1, + const struct wined3d_matrix3 *mat) +{ + struct wined3d_vec3 temp; + + temp.x = (src1->x * mat->_11) + (src1->y * mat->_21) + (src1->z * mat->_31); + temp.y = (src1->x * mat->_12) + (src1->y * mat->_22) + (src1->z * mat->_32); + temp.z = (src1->x * mat->_13) + (src1->y * mat->_23) + (src1->z * mat->_33); + + *dest = temp; +} + +struct light_transformed +{ + struct wined3d_color diffuse, specular, ambient; + struct wined3d_vec4 position; + struct wined3d_vec3 direction; + float range, falloff, c_att, l_att, q_att, cos_htheta, cos_hphi; +}; + +struct lights_settings +{ + struct light_transformed lights[WINED3D_MAX_SOFTWARE_ACTIVE_LIGHTS]; + struct wined3d_color ambient_light; + struct wined3d_matrix modelview_matrix; + struct wined3d_matrix3 normal_matrix; + + DWORD point_light_count : 8; + DWORD spot_light_count : 8; + DWORD directional_light_count : 8; + DWORD parallel_point_light_count : 8; + DWORD legacy_lighting : 1; + DWORD normalize : 1; + DWORD localviewer : 1; + DWORD padding : 29; +}; + +static void init_transformed_lights(struct lights_settings *ls, const struct wined3d_state *state, + BOOL legacy_lighting) +{ + const struct wined3d_light_info *lights[WINED3D_MAX_SOFTWARE_ACTIVE_LIGHTS]; + const struct wined3d_light_info *light_info; + struct light_transformed *light; + unsigned int lights_count; + struct wined3d_vec4 vec4; + unsigned int i, index; + + memset(ls, 0, sizeof(*ls)); + + wined3d_color_from_d3dcolor(&ls->ambient_light, state->render_states[WINED3D_RS_AMBIENT]); + ls->legacy_lighting = !!legacy_lighting; + ls->normalize = !!state->render_states[WINED3D_RS_NORMALIZENORMALS]; + ls->localviewer = !!state->render_states[WINED3D_RS_LOCALVIEWER]; + + multiply_matrix(&ls->modelview_matrix, &state->transforms[WINED3D_TS_VIEW], + &state->transforms[WINED3D_TS_WORLD_MATRIX(0)]); + compute_normal_matrix(&ls->normal_matrix._11, legacy_lighting, &ls->modelview_matrix); + + index = 0; + for (i = 0; i < LIGHTMAP_SIZE && index < WINED3D_MAX_SOFTWARE_ACTIVE_LIGHTS; ++i) + { + LIST_FOR_EACH_ENTRY(light_info, &state->light_state.light_map[i], struct wined3d_light_info, entry) + { + if (!light_info->enabled) + continue; + + switch (light_info->OriginalParms.type) + { + case WINED3D_LIGHT_DIRECTIONAL: + ++ls->directional_light_count; + break; + default: + FIXME("Unhandled light type %#x.\n", light_info->OriginalParms.type); + continue; + } + lights[index] = light_info; + if (++index == WINED3D_MAX_SOFTWARE_ACTIVE_LIGHTS) + break; + } + } + + lights_count = index; + index = 0; + for (i = 0; i < lights_count; ++i) + { + light_info = lights[i]; + if (light_info->OriginalParms.type != WINED3D_LIGHT_DIRECTIONAL) + continue; + + light = &ls->lights[index]; + wined3d_vec4_mat(&vec4, &light_info->direction, &state->transforms[WINED3D_TS_VIEW]); + wined3d_vec3_normalize(&light->direction, (const struct wined3d_vec3 *)&vec4); + + light->diffuse = light_info->OriginalParms.diffuse; + light->ambient = light_info->OriginalParms.ambient; + light->specular = light_info->OriginalParms.specular; + ++index; + } +} + +static void update_light_diffuse_specular(struct wined3d_color *diffuse, struct wined3d_color *specular, + const struct wined3d_vec3 *dir, float att, float material_shininess, + const struct wined3d_vec3 *normal_transformed, + const struct wined3d_vec3 *position_transformed_normalized, + const struct light_transformed *light, const struct lights_settings *ls) +{ + struct wined3d_vec3 vec3; + float t, c; + + c = wined3d_clamp(wined3d_vec3_dot(dir, normal_transformed), 0.0f, 1.0f); + wined3d_color_rgb_mul_add(diffuse, &light->diffuse, c * att); + + if (ls->localviewer) + { + vec3.x = dir->x - position_transformed_normalized->x; + vec3.y = dir->y - position_transformed_normalized->y; + vec3.z = dir->z - position_transformed_normalized->z; + } + else + { + vec3.x = dir->x; + vec3.y = dir->y; + vec3.z = dir->z - 1.0f; + } + wined3d_vec3_normalize(&vec3, &vec3); + t = wined3d_vec3_dot(normal_transformed, &vec3); + if (t > 0.0f && (!ls->legacy_lighting || material_shininess > 0.0f) + && wined3d_vec3_dot(dir, normal_transformed) > 0.0f) + wined3d_color_rgb_mul_add(specular, &light->specular, att * powf(t, material_shininess)); +} + +static void compute_light(struct wined3d_color *ambient, struct wined3d_color *diffuse, + struct wined3d_color *specular, const struct lights_settings *ls, const struct wined3d_vec3 *normal, + const struct wined3d_vec4 *position, float material_shininess) +{ + struct wined3d_vec3 position_transformed_normalized; + struct wined3d_vec3 normal_transformed = {0.0f}; + struct wined3d_vec4 position_transformed; + const struct light_transformed *light; + unsigned int i, index; + float rcp_w; + + wined3d_vec4_mat(&position_transformed, position, &ls->modelview_matrix); + rcp_w = 1.0f / position_transformed.w; + position_transformed.x *= rcp_w; + position_transformed.y *= rcp_w; + position_transformed.z *= rcp_w; + position_transformed.w = 1.0f; + wined3d_vec3_normalize(&position_transformed_normalized, (const struct wined3d_vec3 *)&position_transformed); + + if (normal) + { + wined3d_vec3_m3x3(&normal_transformed, normal, &ls->normal_matrix); + if (ls->normalize) + wined3d_vec3_normalize(&normal_transformed, &normal_transformed); + } + + diffuse->r = diffuse->g = diffuse->b = diffuse->a = 0.0f; + *specular = *diffuse; + *ambient = ls->ambient_light; + + index = 0; + for (i = 0; i < ls->directional_light_count; ++i, ++index) + { + light = &ls->lights[index]; + + wined3d_color_rgb_mul_add(ambient, &light->ambient, 1.0f); + if (normal) + update_light_diffuse_specular(diffuse, specular, &light->direction, 1.0f, material_shininess, + &normal_transformed, &position_transformed_normalized, light, ls); + } +} + /* Context activation is done by the caller. */ #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size) static HRESULT process_vertices_strided(const struct wined3d_device *device, DWORD dwDestIndex, DWORD dwCount, @@ -3204,18 +3409,14 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO struct wined3d_map_desc map_desc; struct wined3d_box box = {0}; struct wined3d_viewport vp; + struct lights_settings ls; unsigned int vertex_size; + BOOL do_clip, lighting; DWORD numTextures; unsigned int i; BYTE *dest_ptr; - BOOL doClip; HRESULT hr;
- if (stream_info->use_map & (1u << WINED3D_FFP_NORMAL)) - { - WARN(" lighting state not saved yet... Some strange stuff may happen !\n"); - } - if (!(stream_info->use_map & (1u << WINED3D_FFP_POSITION))) { ERR("Source has no position mask.\n"); @@ -3231,16 +3432,16 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO * so disable clipping for now. * (The graphics in Half-Life are broken, and my processvertices * test crashes with IDirect3DDevice3) - doClip = TRUE; + do_clip = TRUE; */ - doClip = FALSE; + do_clip = FALSE; if(!warned) { warned = TRUE; FIXME("Clipping is broken and disabled for now\n"); } } else - doClip = FALSE; + do_clip = FALSE;
vertex_size = wined3d_get_flexible_vertex_size(dst_fvf); box.left = dwDestIndex * vertex_size; @@ -3284,21 +3485,27 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
numTextures = (dst_fvf & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
+ lighting = state->render_states[WINED3D_RS_LIGHTING] + && (dst_fvf & (WINED3DFVF_DIFFUSE | WINED3DFVF_SPECULAR)); wined3d_get_mcs(&diffuse_source, &emissive_source, &ambient_source, &specular_source, state, stream_info); - output_color_format = wined3d_get_format(device->adapter, WINED3DFMT_B8G8R8A8_UNORM, 0); material_specular_state_color = state->render_states[WINED3D_RS_SPECULARENABLE] ? &state->material.specular : &black; + if (lighting) + init_transformed_lights(&ls, state, device->adapter->d3d_info.wined3d_creation_flags + & WINED3D_LEGACY_FFP_LIGHTING);
for (i = 0; i < dwCount; i+= 1) { + struct wined3d_color ambient, diffuse, specular; + const struct wined3d_stream_info_element *position_element + = &stream_info->elements[WINED3D_FFP_POSITION]; + const float *p = (const float *)(position_element->data.addr + i * position_element->stride); unsigned int tex_index;
if ( ((dst_fvf & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZ ) || ((dst_fvf & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZRHW ) ) { /* The position first */ - const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_POSITION]; - const float *p = (const float *)(element->data.addr + i * element->stride); float x, y, z, rhw; TRACE("In: ( %06.2f %06.2f %06.2f )\n", p[0], p[1], p[2]);
@@ -3327,10 +3534,9 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO * */
- if( !doClip || - ( (-rhw -eps < x) && (-rhw -eps < y) && ( -eps < z) && - (x <= rhw + eps) && (y <= rhw + eps ) && (z <= rhw + eps) && - ( rhw > eps ) ) ) { + if(!do_clip || (-rhw - eps < x && -rhw - eps < y && -eps < z && x <= rhw + eps + && y <= rhw + eps && z <= rhw + eps && rhw > eps)) + {
/* "Normal" viewport transformation (not clipped) * 1) The values are divided by rhw @@ -3406,25 +3612,77 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO copy_and_next(dest_ptr, normal, 3 * sizeof(float)); }
+ if (lighting) + { + const struct wined3d_stream_info_element *element; + struct wined3d_vec4 position; + struct wined3d_vec3 *normal; + + position.x = p[0]; + position.y = p[1]; + position.z = p[2]; + position.w = 1.0f; + + if (stream_info->use_map & (1u << WINED3D_FFP_NORMAL)) + { + element = &stream_info->elements[WINED3D_FFP_NORMAL]; + normal = (struct wined3d_vec3 *)(element->data.addr + i * element->stride); + } + else + { + normal = NULL; + } + compute_light(&ambient, &diffuse, &specular, &ls, normal, &position, + state->render_states[WINED3D_RS_SPECULARENABLE] ? state->material.power : 0.0f); + } + if (dst_fvf & WINED3DFVF_DIFFUSE) { - struct wined3d_color material_diffuse; + struct wined3d_color material_diffuse, material_ambient, material_emissive, diffuse_color;
color_from_mcs(&material_diffuse, diffuse_source, &state->material.diffuse, i, stream_info);
- wined3d_color_clamp(&material_diffuse, &material_diffuse, 0.0f, 1.0f); - *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_color_format, &material_diffuse); + if (lighting) + { + color_from_mcs(&material_ambient, ambient_source, &state->material.ambient, i, stream_info); + color_from_mcs(&material_emissive, emissive_source, &state->material.emissive, i, stream_info); + + diffuse_color.a = material_diffuse.a; + diffuse_color.r = ambient.r * material_ambient.r + + diffuse.r * material_diffuse.r + material_emissive.r; + diffuse_color.g = ambient.g * material_ambient.g + + diffuse.g * material_diffuse.g + material_emissive.g; + diffuse_color.b = ambient.b * material_ambient.b + + diffuse.b * material_diffuse.b + material_emissive.b; + } + else + { + diffuse_color = material_diffuse; + } + wined3d_color_clamp(&diffuse_color, &diffuse_color, 0.0f, 1.0f); + *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_color_format, &diffuse_color); dest_ptr += sizeof(DWORD); }
if (dst_fvf & WINED3DFVF_SPECULAR) { - struct wined3d_color material_specular; + struct wined3d_color material_specular, specular_color;
color_from_mcs(&material_specular, specular_source, material_specular_state_color, i, stream_info);
- wined3d_color_clamp(&material_specular, &material_specular, 0.0f, 1.0f); - *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_color_format, &material_specular); + if (lighting) + { + specular_color.r = specular.r * material_specular.r; + specular_color.g = specular.g * material_specular.g; + specular_color.b = specular.b * material_specular.b; + specular_color.a = 1.0f; + } + else + { + specular_color = material_specular; + } + wined3d_color_clamp(&specular_color, &specular_color, 0.0f, 1.0f); + *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_color_format, &specular_color); dest_ptr += sizeof(DWORD); }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 57f5e69edc..a44e56c88f 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -270,6 +270,7 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup #define WINED3D_MAX_VERTEX_SAMPLERS 4 #define WINED3D_MAX_COMBINED_SAMPLERS (WINED3D_MAX_FRAGMENT_SAMPLERS + WINED3D_MAX_VERTEX_SAMPLERS) #define WINED3D_MAX_ACTIVE_LIGHTS 8 +#define WINED3D_MAX_SOFTWARE_ACTIVE_LIGHTS 32 #define WINED3D_MAX_CLIP_DISTANCES 8 #define MAX_CONSTANT_BUFFERS 15 #define MAX_SAMPLER_OBJECTS 16
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=52492
Your paranoid android.
=== wvistau64 (64 bit report) ===
ddraw: ddraw1.c:2763: Test failed: Expected message 0x46, but didn't receive it. ddraw1.c:2765: Test failed: Expected screen size 1024x768, got 0x0. ddraw1.c:2771: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2801: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2808: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2834: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2857: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2886: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2912: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2932: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2968: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2978: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3004: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3027: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3049: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3075: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3095: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3132: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746).
Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/ddraw/tests/ddraw1.c | 288 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 288 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 9525b2dc0c..7c9721e78a 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -415,6 +415,27 @@ static void emit_tquad_tlist(void **ptr, WORD base_idx) *ptr = tri; }
+static void emit_tri_indices(void **ptr, WORD *indices, unsigned int primitive_count) +{ + D3DINSTRUCTION *inst = *ptr; + D3DTRIANGLE *tri = (D3DTRIANGLE *)(inst + 1); + unsigned int i; + + inst->bOpcode = D3DOP_TRIANGLE; + inst->bSize = sizeof(*tri); + inst->wCount = primitive_count; + + for (i = 0; i < primitive_count; ++i) + { + U1(*tri).v1 = indices[i * 3]; + U2(*tri).v2 = indices[i * 3 + 1]; + U3(*tri).v3 = indices[i * 3 + 2]; + tri->wFlags = D3DTRIFLAG_START; + ++tri; + } + *ptr = tri; +} + static void emit_texture_load(void **ptr, D3DTEXTUREHANDLE dst_texture, D3DTEXTUREHANDLE src_texture) { @@ -679,6 +700,22 @@ static IDirect3DMaterial *create_emissive_material(IDirect3DDevice *device, floa return create_material(device, &mat); }
+static IDirect3DMaterial *create_specular_material(IDirect3DDevice *device, + float r, float g, float b, float a, float power) +{ + D3DMATERIAL mat; + + memset(&mat, 0, sizeof(mat)); + mat.dwSize = sizeof(mat); + U1(U2(mat).specular).r = r; + U2(U2(mat).specular).g = g; + U3(U2(mat).specular).b = b; + U4(U2(mat).specular).a = a; + U4(mat).power = power; + + return create_material(device, &mat); +} + static void destroy_material(IDirect3DMaterial *material) { IDirect3DMaterial_Release(material); @@ -6294,6 +6331,256 @@ static void test_lighting(void) DestroyWindow(window); }
+static void test_specular_lighting(void) +{ + static const unsigned int vertices_side = 5; + const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3; + const unsigned int vertex_count = vertices_side * vertices_side; + static D3DRECT clear_rect = {{0}, {0}, {640}, {480}}; + static D3DMATRIX mat = + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + }; + /* Use of D3DLIGHT2 instead of D3DLIGHT is intentional. Using D3DLIGHT + without dwFlags looks broken on Windows 7: directional light behaves + as if _LOCALVIEWER state is off, point and spot lights do not work + at all and always output zero colors. */ + static D3DLIGHT2 directional = + { + sizeof(D3DLIGHT2), + D3DLIGHT_DIRECTIONAL, + {{1.0f}, {1.0f}, {1.0f}, {0.0f}}, + {{0.0f}, {0.0f}, {0.0f}}, + {{0.0f}, {0.0f}, {1.0f}}, + }; + static const struct expected_color + { + unsigned int x, y; + D3DCOLOR color; + } + expected_directional_local[] = + { + {160, 120, 0x003c3c3c}, + {320, 120, 0x00717171}, + {480, 120, 0x003c3c3c}, + {160, 240, 0x00717171}, + {320, 240, 0x00ffffff}, + {480, 240, 0x00717171}, + {160, 360, 0x003c3c3c}, + {320, 360, 0x00717171}, + {480, 360, 0x003c3c3c}, + }, + expected_zero[] = + { + {160, 120, 0x00000000}, + {320, 120, 0x00000000}, + {480, 120, 0x00000000}, + {160, 240, 0x00000000}, + {320, 240, 0x00000000}, + {480, 240, 0x00000000}, + {160, 360, 0x00000000}, + {320, 360, 0x00000000}, + {480, 360, 0x00000000}, + }; + static const struct + { + D3DLIGHT2 *light; + float specular_power; + const struct expected_color *expected; + unsigned int expected_count; + } + tests[] = + { + {&directional, 30.0f, expected_directional_local, ARRAY_SIZE(expected_directional_local)}, + {&directional, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, + }; + + D3DMATRIXHANDLE world_handle, view_handle, proj_handle; + IDirect3DMaterial *material, *background_material; + IDirect3DExecuteBuffer *execute_buffer; + D3DEXECUTEBUFFERDESC exec_desc; + D3DMATERIALHANDLE mat_handle; + IDirect3DViewport *viewport; + unsigned int i, j, x, y; + IDirect3DDevice *device; + IDirectDrawSurface *rt; + IDirect3DLight *light; + IDirectDraw*ddraw; + UINT inst_length; + D3DVERTEX *quad; + IDirect3D *d3d; + D3DCOLOR color; + ULONG refcount; + WORD *indices; + BOOL is_warp; + HWND window; + HRESULT hr; + void *ptr; + + window = create_window(); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + if (!(device = create_device(ddraw, window, DDSCL_NORMAL))) + { + skip("Failed to create a 3D device, skipping test.\n"); + IDirectDraw_Release(ddraw); + DestroyWindow(window); + return; + } + is_warp = ddraw_is_warp(ddraw); + + quad = HeapAlloc(GetProcessHeap(), 0, vertex_count * sizeof(*quad)); + indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices)); + for (i = 0, y = 0; y < vertices_side; ++y) + { + for (x = 0; x < vertices_side; ++x) + { + U1(quad[i]).x = x * 2.0f / (vertices_side - 1) - 1.0f; + U2(quad[i]).y = y * 2.0f / (vertices_side - 1) - 1.0f; + U3(quad[i]).z = 1.0f; + U4(quad[i]).nx = 0.0f; + U5(quad[i]).ny = 0.0f; + U6(quad[i]).nz = -1.0f; + U7(quad[i]).tu = 0.0f; + U8(quad[i++]).tv = 0.0f; + } + } + for (i = 0, y = 0; y < (vertices_side - 1); ++y) + { + for (x = 0; x < (vertices_side - 1); ++x) + { + indices[i++] = y * vertices_side + x + 1; + indices[i++] = y * vertices_side + x; + indices[i++] = (y + 1) * vertices_side + x; + indices[i++] = y * vertices_side + x + 1; + indices[i++] = (y + 1) * vertices_side + x; + indices[i++] = (y + 1) * vertices_side + x + 1; + } + } + + hr = IDirect3DDevice_GetDirect3D(device, &d3d); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice_QueryInterface(device, &IID_IDirectDrawSurface, (void **)&rt); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + viewport = create_viewport(device, 0, 0, 640, 480); + background_material = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f); + viewport_set_background(device, viewport, background_material); + + hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice_CreateMatrix(device, &world_handle); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice_SetMatrix(device, world_handle, &mat); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice_CreateMatrix(device, &view_handle); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice_SetMatrix(device, view_handle, &mat); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice_CreateMatrix(device, &proj_handle); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice_SetMatrix(device, proj_handle, &mat); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + + hr = IDirect3D_CreateLight(d3d, &light, NULL); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DViewport_AddLight(viewport, light); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + memset(&exec_desc, 0, sizeof(exec_desc)); + exec_desc.dwSize = sizeof(exec_desc); + exec_desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS; + exec_desc.dwBufferSize = 10240; + exec_desc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY; + + hr = IDirect3DDevice_CreateExecuteBuffer(device, &exec_desc, &execute_buffer, NULL); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + tests[i].light->dwFlags = D3DLIGHT_ACTIVE; + material = create_specular_material(device, 1.0f, 1.0f, 1.0f, 1.0f, tests[i].specular_power); + hr = IDirect3DMaterial_GetHandle(material, device, &mat_handle); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DLight_SetLight(light, (D3DLIGHT *)tests[i].light); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice_BeginScene(device); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DExecuteBuffer_Lock(execute_buffer, &exec_desc); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + memcpy(exec_desc.lpData, quad, sizeof(*quad) * vertex_count); + ptr = ((BYTE *)exec_desc.lpData) + sizeof(*quad) * vertex_count; + + emit_set_ls(&ptr, D3DLIGHTSTATE_MATERIAL, mat_handle); + emit_set_ts(&ptr, D3DTRANSFORMSTATE_WORLD, world_handle); + emit_set_ts(&ptr, D3DTRANSFORMSTATE_VIEW, view_handle); + emit_set_ts(&ptr, D3DTRANSFORMSTATE_PROJECTION, proj_handle); + emit_set_rs(&ptr, D3DRENDERSTATE_ZENABLE, FALSE); + emit_set_rs(&ptr, D3DRENDERSTATE_SPECULARENABLE, TRUE); + + emit_process_vertices(&ptr, D3DPROCESSVERTICES_TRANSFORMLIGHT, 0, vertex_count); + emit_tri_indices(&ptr, indices, indices_count / 3); + emit_end(&ptr); + inst_length = (BYTE *)ptr - (BYTE *)exec_desc.lpData; + ok(inst_length <= exec_desc.dwBufferSize, "Execute buffer overflow, size %u.\n", inst_length); + inst_length -= sizeof(*quad) * vertex_count; + + hr = IDirect3DExecuteBuffer_Unlock(execute_buffer); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + set_execute_data(execute_buffer, vertex_count, sizeof(*quad) * vertex_count, inst_length); + hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice_EndScene(device); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + for (j = 0; j < tests[i].expected_count; ++j) + { + color = get_surface_color(rt, tests[i].expected[j].x, tests[i].expected[j].y); + ok(compare_color(color, tests[i].expected[j].color, 1) + || broken(is_warp && compare_color(color, 0x00ff0000, 1)), + "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n", + tests[i].expected[j].color, tests[i].expected[j].x, + tests[i].expected[j].y, color, i); + } + destroy_material(material); + } + + IDirect3DExecuteBuffer_Release(execute_buffer); + IDirect3DDevice_DeleteMatrix(device, world_handle); + IDirect3DDevice_DeleteMatrix(device, view_handle); + IDirect3DDevice_DeleteMatrix(device, proj_handle); + + hr = IDirect3DViewport_DeleteLight(viewport, light); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + IDirect3DLight_Release(light); + destroy_material(background_material); + destroy_viewport(device, viewport); + IDirectDrawSurface_Release(rt); + refcount = IDirect3DDevice_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + IDirect3D_Release(d3d); + refcount = IDirectDraw_Release(ddraw); + ok(!refcount, "Ddraw object has %u references left.\n", refcount); + DestroyWindow(window); + HeapFree(GetProcessHeap(), 0, indices); + HeapFree(GetProcessHeap(), 0, quad); +} + static void test_palette_gdi(void) { IDirectDrawSurface *surface, *primary; @@ -12552,6 +12839,7 @@ START_TEST(ddraw1) test_p8_blit(); test_material(); test_lighting(); + test_specular_lighting(); test_palette_gdi(); test_palette_alpha(); test_lost_device();
Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/ddraw/tests/ddraw1.c | 62 +++++++++++++++++++++++++++++++++++++++ dlls/wined3d/device.c | 61 +++++++++++++++++++++++++++++++++++++- 2 files changed, 122 insertions(+), 1 deletion(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 7c9721e78a..965b1794b0 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -6355,6 +6355,39 @@ static void test_specular_lighting(void) {{1.0f}, {1.0f}, {1.0f}, {0.0f}}, {{0.0f}, {0.0f}, {0.0f}}, {{0.0f}, {0.0f}, {1.0f}}, + }, + point = + { + sizeof(D3DLIGHT2), + D3DLIGHT_POINT, + {{1.0f}, {1.0f}, {1.0f}, {0.0f}}, + {{0.0f}, {0.0f}, {0.0f}}, + {{0.0f}, {0.0f}, {0.0f}}, + 100.0f, + 0.0f, + 0.0f, 0.0f, 1.0f, + }, + point_side = + { + sizeof(D3DLIGHT2), + D3DLIGHT_POINT, + {{1.0f}, {1.0f}, {1.0f}, {0.0f}}, + {{-1.1f}, {0.0f}, {1.1f}}, + {{0.0f}, {0.0f}, {0.0f}}, + 100.0f, + 0.0f, + 1.0f, 0.0f, 0.0f, + }, + point_far = + { + sizeof(D3DLIGHT2), + D3DLIGHT_POINT, + {{1.0f}, {1.0f}, {1.0f}, {0.0f}}, + {{0.0f}, {0.0f}, {0.1f}}, + {{0.0f}, {0.0f}, {0.0f}}, + 1.0f, + 0.0f, + 1.0f, 0.0f, 0.0f, }; static const struct expected_color { @@ -6373,6 +6406,30 @@ static void test_specular_lighting(void) {320, 360, 0x00717171}, {480, 360, 0x003c3c3c}, }, + expected_point_local[] = + { + {160, 120, 0x00000000}, + {320, 120, 0x00090909}, + {480, 120, 0x00000000}, + {160, 240, 0x00090909}, + {320, 240, 0x00fafafa}, + {480, 240, 0x00090909}, + {160, 360, 0x00000000}, + {320, 360, 0x00090909}, + {480, 360, 0x00000000}, + }, + expected_point_far[] = + { + {160, 120, 0x00000000}, + {320, 120, 0x00000000}, + {480, 120, 0x00000000}, + {160, 240, 0x00000000}, + {320, 240, 0x00ffffff}, + {480, 240, 0x00000000}, + {160, 360, 0x00000000}, + {320, 360, 0x00000000}, + {480, 360, 0x00000000}, + }, expected_zero[] = { {160, 120, 0x00000000}, @@ -6395,7 +6452,12 @@ static void test_specular_lighting(void) tests[] = { {&directional, 30.0f, expected_directional_local, ARRAY_SIZE(expected_directional_local)}, + {&point, 30.0f, expected_point_local, ARRAY_SIZE(expected_point_local)}, + {&point_side, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, + {&point_far, 1.0f, expected_point_far, ARRAY_SIZE(expected_point_far)}, {&directional, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, + {&point, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, + {&point_far, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, };
D3DMATRIXHANDLE world_handle, view_handle, proj_handle; diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index e8835e5548..b3a4c17483 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3293,6 +3293,9 @@ static void init_transformed_lights(struct lights_settings *ls, const struct win case WINED3D_LIGHT_DIRECTIONAL: ++ls->directional_light_count; break; + case WINED3D_LIGHT_POINT: + ++ls->point_light_count; + break; default: FIXME("Unhandled light type %#x.\n", light_info->OriginalParms.type); continue; @@ -3320,6 +3323,26 @@ static void init_transformed_lights(struct lights_settings *ls, const struct win light->specular = light_info->OriginalParms.specular; ++index; } + + for (i = 0; i < lights_count; ++i) + { + light_info = lights[i]; + if (light_info->OriginalParms.type != WINED3D_LIGHT_POINT) + continue; + + light = &ls->lights[index]; + + wined3d_vec4_mat(&light->position, &light_info->position, &state->transforms[WINED3D_TS_VIEW]); + light->range = light_info->OriginalParms.range; + light->c_att = light_info->OriginalParms.attenuation0; + light->l_att = light_info->OriginalParms.attenuation1; + light->q_att = light_info->OriginalParms.attenuation2; + + light->diffuse = light_info->OriginalParms.diffuse; + light->ambient = light_info->OriginalParms.ambient; + light->specular = light_info->OriginalParms.specular; + ++index; + } }
static void update_light_diffuse_specular(struct wined3d_color *diffuse, struct wined3d_color *specular, @@ -3361,8 +3384,9 @@ static void compute_light(struct wined3d_color *ambient, struct wined3d_color *d struct wined3d_vec3 normal_transformed = {0.0f}; struct wined3d_vec4 position_transformed; const struct light_transformed *light; + struct wined3d_vec3 dir, dst; unsigned int i, index; - float rcp_w; + float rcp_w, att;
wined3d_vec4_mat(&position_transformed, position, &ls->modelview_matrix); rcp_w = 1.0f / position_transformed.w; @@ -3393,6 +3417,41 @@ static void compute_light(struct wined3d_color *ambient, struct wined3d_color *d update_light_diffuse_specular(diffuse, specular, &light->direction, 1.0f, material_shininess, &normal_transformed, &position_transformed_normalized, light, ls); } + + for (i = 0; i < ls->point_light_count; ++i, ++index) + { + light = &ls->lights[index]; + dir.x = light->position.x - position_transformed.x; + dir.y = light->position.y - position_transformed.y; + dir.z = light->position.z - position_transformed.z; + + dst.z = wined3d_vec3_dot(&dir, &dir); + dst.y = sqrtf(dst.z); + dst.x = 1.0f; + if (ls->legacy_lighting) + { + dst.y = (light->range - dst.y) / light->range; + if (!(dst.y > 0.0f)) + continue; + dst.z = dst.y * dst.y; + } + else + { + if (!(dst.y <= light->range)) + continue; + } + att = dst.x * light->c_att + dst.y * light->l_att + dst.z * light->q_att; + if (!ls->legacy_lighting) + att = 1.0f / att; + + wined3d_color_rgb_mul_add(ambient, &light->ambient, att); + if (normal) + { + wined3d_vec3_normalize(&dir, &dir); + update_light_diffuse_specular(diffuse, specular, &dir, att, material_shininess, + &normal_transformed, &position_transformed_normalized, light, ls); + } + } }
/* Context activation is done by the caller. */
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=52494
Your paranoid android.
=== wvistau64_he (32 bit report) ===
ddraw: ddraw1.c:2800: Test failed: Expected message 0x46, but didn't receive it. ddraw1.c:2802: Test failed: Expected screen size 1024x768, got 0x0. ddraw1.c:2808: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2838: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2845: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2871: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2894: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2923: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2949: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:2969: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3005: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3015: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3041: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3064: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3086: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3112: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3132: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746). ddraw1.c:3169: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,746).
=== w8 (32 bit report) ===
ddraw: ddraw1.c:1834: Test failed: Got unexpected color 0x000000ff.
=== w1064v1507 (32 bit report) ===
ddraw: ddraw1.c:7486: Test failed: Got unexpected color 0x00000000. ddraw1.c:7490: Test failed: Got unexpected color 0x00000000. ddraw1.c:7553: Test failed: Got unexpected color 0x00000000. ddraw1.c:7555: Test failed: Got unexpected color 0x00000000.
Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/ddraw/tests/ddraw1.c | 26 ++++++++++++++ dlls/wined3d/device.c | 76 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 965b1794b0..0dfc8c48b1 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -6367,6 +6367,18 @@ static void test_specular_lighting(void) 0.0f, 0.0f, 0.0f, 1.0f, }, + spot = + { + sizeof(D3DLIGHT2), + D3DLIGHT_SPOT, + {{1.0f}, {1.0f}, {1.0f}, {0.0f}}, + {{0.0f}, {0.0f}, {0.0f}}, + {{0.0f}, {0.0f}, {1.0f}}, + 100.0f, + 1.0f, + 0.0f, 0.0f, 1.0f, + M_PI / 12.0f, M_PI / 3.0f + }, point_side = { sizeof(D3DLIGHT2), @@ -6418,6 +6430,18 @@ static void test_specular_lighting(void) {320, 360, 0x00090909}, {480, 360, 0x00000000}, }, + expected_spot_local[] = + { + {160, 120, 0x00000000}, + {320, 120, 0x00020202}, + {480, 120, 0x00000000}, + {160, 240, 0x00020202}, + {320, 240, 0x00fafafa}, + {480, 240, 0x00020202}, + {160, 360, 0x00000000}, + {320, 360, 0x00020202}, + {480, 360, 0x00000000}, + }, expected_point_far[] = { {160, 120, 0x00000000}, @@ -6453,10 +6477,12 @@ static void test_specular_lighting(void) { {&directional, 30.0f, expected_directional_local, ARRAY_SIZE(expected_directional_local)}, {&point, 30.0f, expected_point_local, ARRAY_SIZE(expected_point_local)}, + {&spot, 30.0f, expected_spot_local, ARRAY_SIZE(expected_spot_local)}, {&point_side, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, {&point_far, 1.0f, expected_point_far, ARRAY_SIZE(expected_point_far)}, {&directional, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, {&point, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, + {&spot, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, {&point_far, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, };
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index b3a4c17483..5d225df9e3 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3296,6 +3296,9 @@ static void init_transformed_lights(struct lights_settings *ls, const struct win case WINED3D_LIGHT_POINT: ++ls->point_light_count; break; + case WINED3D_LIGHT_SPOT: + ++ls->spot_light_count; + break; default: FIXME("Unhandled light type %#x.\n", light_info->OriginalParms.type); continue; @@ -3343,6 +3346,31 @@ static void init_transformed_lights(struct lights_settings *ls, const struct win light->specular = light_info->OriginalParms.specular; ++index; } + + for (i = 0; i < lights_count; ++i) + { + light_info = lights[i]; + if (light_info->OriginalParms.type != WINED3D_LIGHT_SPOT) + continue; + + light = &ls->lights[index]; + + wined3d_vec4_mat(&light->position, &light_info->position, &state->transforms[WINED3D_TS_VIEW]); + wined3d_vec4_mat(&vec4, &light_info->direction, &state->transforms[WINED3D_TS_VIEW]); + wined3d_vec3_normalize(&light->direction, (const struct wined3d_vec3 *)&vec4); + light->range = light_info->OriginalParms.range; + light->falloff = light_info->OriginalParms.falloff; + light->c_att = light_info->OriginalParms.attenuation0; + light->l_att = light_info->OriginalParms.attenuation1; + light->q_att = light_info->OriginalParms.attenuation2; + light->cos_htheta = cosf(light_info->OriginalParms.theta / 2.0f); + light->cos_hphi = cosf(light_info->OriginalParms.phi / 2.0f); + + light->diffuse = light_info->OriginalParms.diffuse; + light->ambient = light_info->OriginalParms.ambient; + light->specular = light_info->OriginalParms.specular; + ++index; + } }
static void update_light_diffuse_specular(struct wined3d_color *diffuse, struct wined3d_color *specular, @@ -3452,6 +3480,54 @@ static void compute_light(struct wined3d_color *ambient, struct wined3d_color *d &normal_transformed, &position_transformed_normalized, light, ls); } } + + for (i = 0; i < ls->spot_light_count; ++i, ++index) + { + float t; + + light = &ls->lights[index]; + + dir.x = light->position.x - position_transformed.x; + dir.y = light->position.y - position_transformed.y; + dir.z = light->position.z - position_transformed.z; + + dst.z = wined3d_vec3_dot(&dir, &dir); + dst.y = sqrtf(dst.z); + dst.x = 1.0f; + + if (ls->legacy_lighting) + { + dst.y = (light->range - dst.y) / light->range; + if (!(dst.y > 0.0f)) + continue; + dst.z = dst.y * dst.y; + } + else + { + if (!(dst.y <= light->range)) + continue; + } + wined3d_vec3_normalize(&dir, &dir); + t = -wined3d_vec3_dot(&dir, &light->direction); + if (t > light->cos_htheta) + att = 1.0f; + else if (t <= light->cos_hphi) + att = 0.0f; + else + att = powf((t - light->cos_hphi) / (light->cos_htheta - light->cos_hphi), light->falloff); + + t = dst.x * light->c_att + dst.y * light->l_att + dst.z * light->q_att; + if (ls->legacy_lighting) + att *= t; + else + att /= t; + + wined3d_color_rgb_mul_add(ambient, &light->ambient, att); + + if (normal) + update_light_diffuse_specular(diffuse, specular, &dir, att, material_shininess, + &normal_transformed, &position_transformed_normalized, light, ls); + } }
/* Context activation is done by the caller. */
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=52495
Your paranoid android.
=== w1064v1507 (32 bit report) ===
ddraw: ddraw1.c:11002: Test failed: Got unexpected color 0x00ffffff.
Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/ddraw/tests/ddraw1.c | 22 ++++++++++++++++++++++ dlls/wined3d/device.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 0dfc8c48b1..7b4917bb6e 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -6379,6 +6379,14 @@ static void test_specular_lighting(void) 0.0f, 0.0f, 1.0f, M_PI / 12.0f, M_PI / 3.0f }, + parallelpoint = + { + sizeof(D3DLIGHT2), + D3DLIGHT_PARALLELPOINT, + {{1.0f}, {1.0f}, {1.0f}, {0.0f}}, + {{0.5f}, {0.0f}, {-1.0f}}, + {{0.0f}, {0.0f}, {0.0f}}, + }, point_side = { sizeof(D3DLIGHT2), @@ -6442,6 +6450,18 @@ static void test_specular_lighting(void) {320, 360, 0x00020202}, {480, 360, 0x00000000}, }, + expected_parallelpoint[] = + { + {160, 120, 0x00050505}, + {320, 120, 0x002c2c2c}, + {480, 120, 0x006e6e6e}, + {160, 240, 0x00090909}, + {320, 240, 0x00717171}, + {480, 240, 0x00ffffff}, + {160, 360, 0x00050505}, + {320, 360, 0x002c2c2c}, + {480, 360, 0x006e6e6e}, + }, expected_point_far[] = { {160, 120, 0x00000000}, @@ -6478,11 +6498,13 @@ static void test_specular_lighting(void) {&directional, 30.0f, expected_directional_local, ARRAY_SIZE(expected_directional_local)}, {&point, 30.0f, expected_point_local, ARRAY_SIZE(expected_point_local)}, {&spot, 30.0f, expected_spot_local, ARRAY_SIZE(expected_spot_local)}, + {¶llelpoint, 30.0f, expected_parallelpoint, ARRAY_SIZE(expected_parallelpoint)}, {&point_side, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, {&point_far, 1.0f, expected_point_far, ARRAY_SIZE(expected_point_far)}, {&directional, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, {&point, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, {&spot, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, + {¶llelpoint, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, {&point_far, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)}, };
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 5d225df9e3..7252823f2e 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3299,6 +3299,9 @@ static void init_transformed_lights(struct lights_settings *ls, const struct win case WINED3D_LIGHT_SPOT: ++ls->spot_light_count; break; + case WINED3D_LIGHT_PARALLELPOINT: + ++ls->parallel_point_light_count; + break; default: FIXME("Unhandled light type %#x.\n", light_info->OriginalParms.type); continue; @@ -3371,6 +3374,22 @@ static void init_transformed_lights(struct lights_settings *ls, const struct win light->specular = light_info->OriginalParms.specular; ++index; } + + for (i = 0; i < lights_count; ++i) + { + light_info = lights[i]; + if (light_info->OriginalParms.type != WINED3D_LIGHT_PARALLELPOINT) + continue; + + light = &ls->lights[index]; + + wined3d_vec4_mat(&vec4, &light_info->position, &state->transforms[WINED3D_TS_VIEW]); + wined3d_vec3_normalize((struct wined3d_vec3 *)&light->position, (const struct wined3d_vec3 *)&vec4); + light->diffuse = light_info->OriginalParms.diffuse; + light->ambient = light_info->OriginalParms.ambient; + light->specular = light_info->OriginalParms.specular; + ++index; + } }
static void update_light_diffuse_specular(struct wined3d_color *diffuse, struct wined3d_color *specular, @@ -3528,6 +3547,16 @@ static void compute_light(struct wined3d_color *ambient, struct wined3d_color *d update_light_diffuse_specular(diffuse, specular, &dir, att, material_shininess, &normal_transformed, &position_transformed_normalized, light, ls); } + + for (i = 0; i < ls->parallel_point_light_count; ++i, ++index) + { + light = &ls->lights[index]; + + wined3d_color_rgb_mul_add(ambient, &light->ambient, 1.0f); + if (normal) + update_light_diffuse_specular(diffuse, specular, (const struct wined3d_vec3 *)&light->position, + 1.0f, material_shininess, &normal_transformed, &position_transformed_normalized, light, ls); + } }
/* Context activation is done by the caller. */
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=52496
Your paranoid android.
=== wvistau64_zh_CN (32 bit report) ===
ddraw: ddraw1.c:2800: Test failed: Expected message 0x46, but didn't receive it. ddraw1.c:2802: Test failed: Expected screen size 1024x768, got 0x0. ddraw1.c:2808: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,745). ddraw1.c:2838: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,745). ddraw1.c:2845: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,745). ddraw1.c:2871: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,745). ddraw1.c:2894: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,745). ddraw1.c:2923: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,745). ddraw1.c:2949: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,745). ddraw1.c:2969: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,745). ddraw1.c:3005: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,745). ddraw1.c:3015: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,745). ddraw1.c:3041: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,745). ddraw1.c:3064: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,745). ddraw1.c:3086: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,745). ddraw1.c:3112: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,745). ddraw1.c:3132: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,745). ddraw1.c:3169: Test failed: Expected (0,0)-(1024,768), got (-8,-8)-(1032,745).
=== w864 (32 bit report) ===
ddraw: ddraw1.c:7534: Test failed: Got unexpected color 0x00000000. ddraw1.c:7538: Test failed: Got unexpected color 0x00000000. ddraw1.c:7601: Test failed: Got unexpected color 0x00000000. ddraw1.c:7603: Test failed: Got unexpected color 0x00000000.