Wine-devel
Threads by month
- ----- 2026 -----
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
May 2019
- 96 participants
- 789 discussions
[PATCH 2/5] wined3d: Pass a wined3d_context_gl structure to context_update_window().
by Henri Verbeet 20 May '19
by Henri Verbeet 20 May '19
20 May '19
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/context.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index db0c9f2a372..e2e67ef957b 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -1297,30 +1297,30 @@ static void context_restore_gl_context(const struct wined3d_gl_info *gl_info, HD
}
}
-static void context_update_window(struct wined3d_context *context)
+static void wined3d_context_gl_update_window(struct wined3d_context_gl *context_gl)
{
- if (!context->swapchain)
+ if (!context_gl->c.swapchain)
return;
- if (context->win_handle == context->swapchain->win_handle)
+ if (context_gl->c.win_handle == context_gl->c.swapchain->win_handle)
return;
TRACE("Updating context %p window from %p to %p.\n",
- context, context->win_handle, context->swapchain->win_handle);
+ context_gl, context_gl->c.win_handle, context_gl->c.swapchain->win_handle);
- if (context->hdc)
- wined3d_release_dc(context->win_handle, context->hdc);
+ if (context_gl->c.hdc)
+ wined3d_release_dc(context_gl->c.win_handle, context_gl->c.hdc);
- context->win_handle = context->swapchain->win_handle;
- context->hdc_is_private = FALSE;
- context->hdc_has_format = FALSE;
- context->needs_set = 1;
- context->valid = 1;
+ context_gl->c.win_handle = context_gl->c.swapchain->win_handle;
+ context_gl->c.hdc_is_private = FALSE;
+ context_gl->c.hdc_has_format = FALSE;
+ context_gl->c.needs_set = 1;
+ context_gl->c.valid = 1;
- if (!(context->hdc = GetDCEx(context->win_handle, 0, DCX_USESTYLE | DCX_CACHE)))
+ if (!(context_gl->c.hdc = GetDCEx(context_gl->c.win_handle, 0, DCX_USESTYLE | DCX_CACHE)))
{
- ERR("Failed to get a device context for window %p.\n", context->win_handle);
- context->valid = 0;
+ ERR("Failed to get a device context for window %p.\n", context_gl->c.win_handle);
+ context_gl->c.valid = 0;
}
}
@@ -4218,7 +4218,7 @@ static void context_activate(struct wined3d_context *context,
struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
context_enter(context);
- context_update_window(context);
+ wined3d_context_gl_update_window(context_gl);
context_setup_target(context, texture, sub_resource_idx);
if (!context->valid)
return;
--
2.11.0
1
0
[PATCH 1/5] wined3d: Pass a wined3d_context_gl structure to context_set_gl_context().
by Henri Verbeet 20 May '19
by Henri Verbeet 20 May '19
20 May '19
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/context.c | 46 +++++++++++++++++++++++++---------------------
1 file changed, 25 insertions(+), 21 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index aa4d2601b68..db0c9f2a372 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -1225,65 +1225,65 @@ success:
return TRUE;
}
-static BOOL context_set_gl_context(struct wined3d_context *ctx)
+static BOOL wined3d_context_gl_set_gl_context(struct wined3d_context_gl *context_gl)
{
- struct wined3d_context_gl *context_gl = wined3d_context_gl(ctx);
- struct wined3d_swapchain *swapchain = ctx->swapchain;
+ struct wined3d_swapchain *swapchain = context_gl->c.swapchain;
BOOL backup = FALSE;
if (!wined3d_context_gl_set_pixel_format(context_gl))
{
WARN("Failed to set pixel format %d on device context %p.\n",
- ctx->pixel_format, ctx->hdc);
+ context_gl->c.pixel_format, context_gl->c.hdc);
backup = TRUE;
}
- if (backup || !wglMakeCurrent(ctx->hdc, ctx->glCtx))
+ if (backup || !wglMakeCurrent(context_gl->c.hdc, context_gl->c.glCtx))
{
WARN("Failed to make GL context %p current on device context %p, last error %#x.\n",
- ctx->glCtx, ctx->hdc, GetLastError());
- ctx->valid = 0;
+ context_gl->c.glCtx, context_gl->c.hdc, GetLastError());
+ context_gl->c.valid = 0;
WARN("Trying fallback to the backup window.\n");
/* FIXME: If the context is destroyed it's no longer associated with
* a swapchain, so we can't use the swapchain to get a backup dc. To
* make this work windowless contexts would need to be handled by the
* device. */
- if (ctx->destroyed || !swapchain)
+ if (context_gl->c.destroyed || !swapchain)
{
- FIXME("Unable to get backup dc for destroyed context %p.\n", ctx);
+ FIXME("Unable to get backup dc for destroyed context %p.\n", context_gl);
context_set_current(NULL);
return FALSE;
}
- if (!(ctx->hdc = swapchain_get_backup_dc(swapchain)))
+ if (!(context_gl->c.hdc = swapchain_get_backup_dc(swapchain)))
{
context_set_current(NULL);
return FALSE;
}
- ctx->hdc_is_private = TRUE;
- ctx->hdc_has_format = FALSE;
+ context_gl->c.hdc_is_private = TRUE;
+ context_gl->c.hdc_has_format = FALSE;
if (!wined3d_context_gl_set_pixel_format(context_gl))
{
ERR("Failed to set pixel format %d on device context %p.\n",
- ctx->pixel_format, ctx->hdc);
+ context_gl->c.pixel_format, context_gl->c.hdc);
context_set_current(NULL);
return FALSE;
}
- if (!wglMakeCurrent(ctx->hdc, ctx->glCtx))
+ if (!wglMakeCurrent(context_gl->c.hdc, context_gl->c.glCtx))
{
ERR("Fallback to backup window (dc %p) failed too, last error %#x.\n",
- ctx->hdc, GetLastError());
+ context_gl->c.hdc, GetLastError());
context_set_current(NULL);
return FALSE;
}
- ctx->valid = 1;
+ context_gl->c.valid = 1;
}
- ctx->needs_set = 0;
+ context_gl->c.needs_set = 0;
+
return TRUE;
}
@@ -1337,7 +1337,7 @@ void wined3d_context_cleanup(struct wined3d_context *context)
if (restore_ctx == context->glCtx)
restore_ctx = NULL;
else if (context->valid)
- context_set_gl_context(context);
+ wined3d_context_gl_set_gl_context(context_gl);
wined3d_context_gl_restore_pixel_format(context_gl);
if (restore_ctx)
@@ -1377,7 +1377,7 @@ void wined3d_context_gl_cleanup(struct wined3d_context_gl *context_gl)
if (restore_ctx == context_gl->c.glCtx)
restore_ctx = NULL;
else if (context_gl->c.valid)
- context_set_gl_context(&context_gl->c);
+ wined3d_context_gl_set_gl_context(context_gl);
if (context_gl->c.valid)
{
@@ -1557,6 +1557,8 @@ BOOL context_set_current(struct wined3d_context *ctx)
if (ctx)
{
+ struct wined3d_context_gl *context_gl = wined3d_context_gl(ctx);
+
if (!ctx->valid)
{
ERR("Trying to make invalid context %p current\n", ctx);
@@ -1564,7 +1566,7 @@ BOOL context_set_current(struct wined3d_context *ctx)
}
TRACE("Switching to D3D context %p, GL context %p, device context %p.\n", ctx, ctx->glCtx, ctx->hdc);
- if (!context_set_gl_context(ctx))
+ if (!wined3d_context_gl_set_gl_context(context_gl))
return FALSE;
ctx->current = 1;
}
@@ -4213,6 +4215,8 @@ static void context_setup_target(struct wined3d_context *context,
static void context_activate(struct wined3d_context *context,
struct wined3d_texture *texture, unsigned int sub_resource_idx)
{
+ struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
+
context_enter(context);
context_update_window(context);
context_setup_target(context, texture, sub_resource_idx);
@@ -4226,7 +4230,7 @@ static void context_activate(struct wined3d_context *context,
}
else if (context->needs_set)
{
- context_set_gl_context(context);
+ wined3d_context_gl_set_gl_context(context_gl);
}
}
--
2.11.0
1
0
20 May '19
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
v2: Move setting feature_level to the end of d3d_info initialization,
pass a struct wined3d_d3d_limits around instead of the whole d3d_info.
dlls/d3d9/device.c | 4 ++--
dlls/wined3d/adapter_gl.c | 20 +++++++++++++++-----
dlls/wined3d/directx.c | 10 +++++-----
dlls/wined3d/shader.c | 4 ++--
dlls/wined3d/utils.c | 4 ++--
include/wine/wined3d.h | 4 ++--
6 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index bef01a477f9..9fbdcebf075 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -4443,8 +4443,8 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine
static const enum wined3d_feature_level feature_levels[] =
{
- WINED3D_FEATURE_LEVEL_9_SM3,
- WINED3D_FEATURE_LEVEL_9_SM2,
+ WINED3D_FEATURE_LEVEL_9_3,
+ WINED3D_FEATURE_LEVEL_9_2,
WINED3D_FEATURE_LEVEL_9_1,
WINED3D_FEATURE_LEVEL_8,
WINED3D_FEATURE_LEVEL_7,
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 5524f948c62..818fa8407aa 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -1241,7 +1241,8 @@ static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_s
}
static enum wined3d_feature_level feature_level_from_caps(const struct wined3d_gl_info *gl_info,
- const struct shader_caps *shader_caps, const struct fragment_caps *fragment_caps)
+ const struct wined3d_d3d_limits *d3d_limits, const struct shader_caps *shader_caps,
+ const struct fragment_caps *fragment_caps)
{
unsigned int shader_model;
@@ -1267,10 +1268,18 @@ static enum wined3d_feature_level feature_level_from_caps(const struct wined3d_g
}
}
- if (shader_model >= 3)
- return WINED3D_FEATURE_LEVEL_9_SM3;
+ if (shader_model >= 3 && d3d_limits->texture_size >= 4096 && d3d_limits->max_rt_count >= 4)
+ return WINED3D_FEATURE_LEVEL_9_3;
if (shader_model >= 2)
- return WINED3D_FEATURE_LEVEL_9_SM2;
+ {
+ if (gl_info->supported[ARB_OCCLUSION_QUERY]
+ && gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE]
+ && gl_info->supported[EXT_BLEND_EQUATION_SEPARATE]
+ && gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
+ return WINED3D_FEATURE_LEVEL_9_2;
+
+ return WINED3D_FEATURE_LEVEL_9_1;
+ }
if (shader_model >= 1)
return WINED3D_FEATURE_LEVEL_8;
@@ -3722,7 +3731,6 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
d3d_info->limits.ffp_textures = fragment_caps.MaxSimultaneousTextures;
d3d_info->shader_color_key = !!(fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_COLOR_KEY);
d3d_info->wined3d_creation_flags = wined3d_creation_flags;
- d3d_info->feature_level = feature_level_from_caps(gl_info, &shader_caps, &fragment_caps);
d3d_info->texture_npot = !!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO];
d3d_info->texture_npot_conditional = gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]
@@ -3737,6 +3745,8 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
else
d3d_info->multisample_draw_location = WINED3D_LOCATION_RB_MULTISAMPLE;
+ d3d_info->feature_level = feature_level_from_caps(gl_info, &d3d_info->limits, &shader_caps, &fragment_caps);
+
TRACE("Max texture stages: %u.\n", d3d_info->limits.ffp_blend_stages);
if (!d3d_info->shader_color_key)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 12c83bb2cd9..39dd13a9292 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -691,8 +691,8 @@ enum wined3d_pci_device wined3d_gpu_from_feature_level(enum wined3d_pci_vendor *
{WINED3D_FEATURE_LEVEL_6, CARD_NVIDIA_RIVA_TNT},
{WINED3D_FEATURE_LEVEL_7, CARD_NVIDIA_GEFORCE},
{WINED3D_FEATURE_LEVEL_8, CARD_NVIDIA_GEFORCE3},
- {WINED3D_FEATURE_LEVEL_9_SM2, CARD_NVIDIA_GEFORCEFX_5800},
- {WINED3D_FEATURE_LEVEL_9_SM3, CARD_NVIDIA_GEFORCE_6800},
+ {WINED3D_FEATURE_LEVEL_9_2, CARD_NVIDIA_GEFORCEFX_5800},
+ {WINED3D_FEATURE_LEVEL_9_3, CARD_NVIDIA_GEFORCE_6800},
{WINED3D_FEATURE_LEVEL_10, CARD_NVIDIA_GEFORCE_8800GTX},
{WINED3D_FEATURE_LEVEL_11, CARD_NVIDIA_GEFORCE_GTX470},
{WINED3D_FEATURE_LEVEL_NONE},
@@ -702,8 +702,8 @@ enum wined3d_pci_device wined3d_gpu_from_feature_level(enum wined3d_pci_vendor *
{WINED3D_FEATURE_LEVEL_5, CARD_AMD_RAGE_128PRO},
{WINED3D_FEATURE_LEVEL_7, CARD_AMD_RADEON_7200},
{WINED3D_FEATURE_LEVEL_8, CARD_AMD_RADEON_8500},
- {WINED3D_FEATURE_LEVEL_9_SM2, CARD_AMD_RADEON_9500},
- {WINED3D_FEATURE_LEVEL_9_SM3, CARD_AMD_RADEON_X1600},
+ {WINED3D_FEATURE_LEVEL_9_1, CARD_AMD_RADEON_9500},
+ {WINED3D_FEATURE_LEVEL_9_3, CARD_AMD_RADEON_X1600},
{WINED3D_FEATURE_LEVEL_10, CARD_AMD_RADEON_HD2900},
{WINED3D_FEATURE_LEVEL_11, CARD_AMD_RADEON_HD5600},
{WINED3D_FEATURE_LEVEL_NONE},
@@ -712,7 +712,7 @@ enum wined3d_pci_device wined3d_gpu_from_feature_level(enum wined3d_pci_vendor *
{
{WINED3D_FEATURE_LEVEL_5, CARD_INTEL_845G},
{WINED3D_FEATURE_LEVEL_8, CARD_INTEL_915G},
- {WINED3D_FEATURE_LEVEL_9_SM3, CARD_INTEL_945G},
+ {WINED3D_FEATURE_LEVEL_9_3, CARD_INTEL_945G},
{WINED3D_FEATURE_LEVEL_10, CARD_INTEL_G45},
{WINED3D_FEATURE_LEVEL_11, CARD_INTEL_IVBD},
{WINED3D_FEATURE_LEVEL_NONE},
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 609b574d461..a8fee07c6c3 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -3311,9 +3311,9 @@ static unsigned int shader_max_version_from_feature_level(enum wined3d_feature_l
case WINED3D_FEATURE_LEVEL_10_1:
case WINED3D_FEATURE_LEVEL_10:
return 4;
- case WINED3D_FEATURE_LEVEL_9_SM3:
+ case WINED3D_FEATURE_LEVEL_9_3:
return 3;
- case WINED3D_FEATURE_LEVEL_9_SM2:
+ case WINED3D_FEATURE_LEVEL_9_2:
case WINED3D_FEATURE_LEVEL_9_1:
return 2;
default:
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index ef469100fdc..6a880bb2d70 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -6573,8 +6573,8 @@ const char *wined3d_debug_feature_level(enum wined3d_feature_level level)
LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_7);
LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_8);
LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_9_1);
- LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_9_SM2);
- LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_9_SM3);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_9_2);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_9_3);
LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_10);
LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_10_1);
LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_11);
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 958ade166c0..31afa46623f 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -96,8 +96,8 @@ enum wined3d_feature_level
WINED3D_FEATURE_LEVEL_7 = 0x7000,
WINED3D_FEATURE_LEVEL_8 = 0x8000,
WINED3D_FEATURE_LEVEL_9_1 = 0x9100,
- WINED3D_FEATURE_LEVEL_9_SM2 = 0x9200,
- WINED3D_FEATURE_LEVEL_9_SM3 = 0x9300,
+ WINED3D_FEATURE_LEVEL_9_2 = 0x9200,
+ WINED3D_FEATURE_LEVEL_9_3 = 0x9300,
WINED3D_FEATURE_LEVEL_10 = 0xa000,
WINED3D_FEATURE_LEVEL_10_1 = 0xa100,
WINED3D_FEATURE_LEVEL_11 = 0xb000,
--
2.21.0
3
14
20 May '19
From: Paul Gofman <gofmanp(a)gmail.com>
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/ddraw/tests/ddraw1.c | 289 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 289 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index 9525b2dc0c1..22b43c42295 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -20,6 +20,7 @@
#define COBJMACROS
#include "wine/test.h"
+#include "wine/heap.h"
#include <limits.h>
#include <math.h>
#include "ddrawi.h"
@@ -415,6 +416,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 +701,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 +6332,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 colours. */
+ 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 colour;
+ }
+ 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;
+ D3DCOLOR colour;
+ IDirect3D *d3d;
+ 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 = heap_alloc(vertex_count * sizeof(*quad));
+ indices = heap_alloc(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)
+ {
+ colour = get_surface_color(rt, tests[i].expected[j].x, tests[i].expected[j].y);
+ ok(compare_color(colour, tests[i].expected[j].colour, 1)
+ || broken(is_warp && compare_color(colour, 0x00ff0000, 1)),
+ "Expected colour 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
+ tests[i].expected[j].colour, tests[i].expected[j].x,
+ tests[i].expected[j].y, colour, 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);
+ heap_free(indices);
+ heap_free(quad);
+}
+
static void test_palette_gdi(void)
{
IDirectDrawSurface *surface, *primary;
@@ -12552,6 +12840,7 @@ START_TEST(ddraw1)
test_p8_blit();
test_material();
test_lighting();
+ test_specular_lighting();
test_palette_gdi();
test_palette_alpha();
test_lost_device();
--
2.11.0
2
1
[PATCH 4/8] wined3d: Implement lighting with directional lights in process_vertices_strided().
by Henri Verbeet 20 May '19
by Henri Verbeet 20 May '19
20 May '19
From: Paul Gofman <gofmanp(a)gmail.com>
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/ddraw/tests/ddraw1.c | 4 +-
dlls/wined3d/device.c | 311 +++++++++++++++++++++++++++++++++++++----
dlls/wined3d/wined3d_private.h | 1 +
3 files changed, 289 insertions(+), 27 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index 7dda6eba201..9525b2dc0c1 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 8c77b3b590f..23aca23d24d 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -37,6 +37,39 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(winediag);
+struct wined3d_matrix_3x3
+{
+ float _11, _12, _13;
+ float _21, _22, _23;
+ float _31, _32, _33;
+};
+
+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_matrix_3x3 normal_matrix;
+
+ uint32_t point_light_count : 8;
+ uint32_t spot_light_count : 8;
+ uint32_t directional_light_count : 8;
+ uint32_t parallel_point_light_count : 8;
+
+ uint32_t legacy_lighting : 1;
+ uint32_t normalise : 1;
+ uint32_t localviewer : 1;
+ uint32_t padding : 29;
+};
+
/* Define the default light parameters as specified by MSDN. */
const struct wined3d_light WINED3D_default_light =
{
@@ -3170,6 +3203,45 @@ 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 float wined3d_vec3_dot(const struct wined3d_vec3 *v0, const struct wined3d_vec3 *v1)
+{
+ return v0->x * v1->x + v0->y * v1->y + v0->z * v1->z;
+}
+
+static void wined3d_vec3_subtract(struct wined3d_vec3 *v0, const struct wined3d_vec3 *v1)
+{
+ v0->x -= v1->x;
+ v0->y -= v1->y;
+ v0->z -= v1->z;
+}
+
+static void wined3d_vec3_scale(struct wined3d_vec3 *v, float s)
+{
+ v->x *= s;
+ v->y *= s;
+ v->z *= s;
+}
+
+static void wined3d_vec3_normalise(struct wined3d_vec3 *v)
+{
+ float rnorm = 1.0f / sqrtf(wined3d_vec3_dot(v, v));
+
+ if (isfinite(rnorm))
+ wined3d_vec3_scale(v, rnorm);
+}
+
+static void wined3d_vec3_transform(struct wined3d_vec3 *dst,
+ const struct wined3d_vec3 *v, const struct wined3d_matrix_3x3 *m)
+{
+ struct wined3d_vec3 tmp;
+
+ tmp.x = v->x * m->_11 + v->y * m->_21 + v->z * m->_31;
+ tmp.y = v->x * m->_12 + v->y * m->_22 + v->z * m->_32;
+ tmp.z = v->x * m->_13 + v->y * m->_23 + v->z * m->_33;
+
+ *dst = tmp;
+}
+
static void wined3d_color_clamp(struct wined3d_color *dst, const struct wined3d_color *src,
float min_value, float max_value)
{
@@ -3179,6 +3251,138 @@ 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_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;
+}
+
+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;
+ struct wined3d_vec4 vec4;
+ unsigned int light_count;
+ 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->normalise = !!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);
+
+ for (i = 0, index = 0; i < LIGHTMAP_SIZE && index < ARRAY_SIZE(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;
+ }
+ }
+
+ light_count = index;
+ for (i = 0, index = 0; i < light_count; ++i)
+ {
+ light_info = lights[i];
+ if (light_info->OriginalParms.type != WINED3D_LIGHT_DIRECTIONAL)
+ continue;
+
+ light = &ls->lights[index];
+ wined3d_vec4_transform(&vec4, &light_info->direction, &state->transforms[WINED3D_TS_VIEW]);
+ light->direction = *(struct wined3d_vec3 *)&vec4;
+ wined3d_vec3_normalise(&light->direction);
+
+ 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_normalised,
+ 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);
+
+ vec3 = *dir;
+ if (ls->localviewer)
+ wined3d_vec3_subtract(&vec3, position_transformed_normalised);
+ else
+ vec3.z -= 1.0f;
+ wined3d_vec3_normalise(&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_normalised;
+ struct wined3d_vec3 normal_transformed = {0.0f};
+ struct wined3d_vec4 position_transformed;
+ const struct light_transformed *light;
+ unsigned int i, index;
+
+ wined3d_vec4_transform(&position_transformed, position, &ls->modelview_matrix);
+ position_transformed_normalised = *(const struct wined3d_vec3 *)&position_transformed;
+ wined3d_vec3_scale(&position_transformed_normalised, 1.0f / position_transformed.w);
+ wined3d_vec3_normalise(&position_transformed_normalised);
+
+ if (normal)
+ {
+ wined3d_vec3_transform(&normal_transformed, normal, &ls->normal_matrix);
+ if (ls->normalise)
+ wined3d_vec3_normalise(&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_normalised, 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,
@@ -3194,17 +3398,13 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
struct wined3d_box box = {0};
struct wined3d_viewport vp;
unsigned int texture_count;
+ struct lights_settings ls;
unsigned int vertex_size;
+ BOOL do_clip, lighting;
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");
@@ -3220,16 +3420,17 @@ 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;
- if(!warned) {
+ 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;
@@ -3273,21 +3474,27 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
texture_count = (dst_fvf & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
+ lighting = state->render_states[WINED3D_RS_LIGHTING]
+ && (dst_fvf & (WINED3DFVF_DIFFUSE | WINED3DFVF_SPECULAR));
wined3d_get_material_colour_source(&diffuse_source, &emissive_source,
&ambient_source, &specular_source, state, stream_info);
-
output_colour_format = wined3d_get_format(device->adapter, WINED3DFMT_B8G8R8A8_UNORM, 0);
material_specular_state_colour = 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) {
+ for (i = 0; i < dwCount; ++i)
+ {
+ 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];
+ struct wined3d_color ambient, diffuse, specular;
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]);
@@ -3316,11 +3523,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
* 2) The y axis is negative, so multiply it with -1
@@ -3395,25 +3600,81 @@ 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_colour;
wined3d_colour_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_colour_format, &material_diffuse);
+
+ if (lighting)
+ {
+ wined3d_colour_from_mcs(&material_ambient, ambient_source,
+ &state->material.ambient, i, stream_info);
+ wined3d_colour_from_mcs(&material_emissive, emissive_source,
+ &state->material.emissive, i, stream_info);
+
+ diffuse_colour.r = ambient.r * material_ambient.r
+ + diffuse.r * material_diffuse.r + material_emissive.r;
+ diffuse_colour.g = ambient.g * material_ambient.g
+ + diffuse.g * material_diffuse.g + material_emissive.g;
+ diffuse_colour.b = ambient.b * material_ambient.b
+ + diffuse.b * material_diffuse.b + material_emissive.b;
+ diffuse_colour.a = material_diffuse.a;
+ }
+ else
+ {
+ diffuse_colour = material_diffuse;
+ }
+ wined3d_color_clamp(&diffuse_colour, &diffuse_colour, 0.0f, 1.0f);
+ *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_colour_format, &diffuse_colour);
dest_ptr += sizeof(DWORD);
}
if (dst_fvf & WINED3DFVF_SPECULAR)
{
- struct wined3d_color material_specular;
+ struct wined3d_color material_specular, specular_colour;
wined3d_colour_from_mcs(&material_specular, specular_source,
material_specular_state_colour, i, stream_info);
- wined3d_color_clamp(&material_specular, &material_specular, 0.0f, 1.0f);
- *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_colour_format, &material_specular);
+
+ if (lighting)
+ {
+ specular_colour.r = specular.r * material_specular.r;
+ specular_colour.g = specular.g * material_specular.g;
+ specular_colour.b = specular.b * material_specular.b;
+ specular_colour.a = 1.0f;
+ }
+ else
+ {
+ specular_colour = material_specular;
+ }
+ wined3d_color_clamp(&specular_colour, &specular_colour, 0.0f, 1.0f);
+ *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_colour_format, &specular_colour);
dest_ptr += sizeof(DWORD);
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index a74a837c43b..9c0efc7c50d 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
--
2.11.0
2
1
[PATCH v2 1/7] wined3d: Use color source for output colors in process_vertices_strided().
by Paul Gofman 20 May '19
by Paul Gofman 20 May '19
20 May '19
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
---
v2 changes:
- 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.
dlls/wined3d/device.c | 198 ++++++++++++++++++++++++++++++++++--------
1 file changed, 161 insertions(+), 37 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 5272e2ef23..81a76398a7 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3072,20 +3072,141 @@ 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;
+
+ 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 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 = clamp(src->r, min_value, max_value);
+ dst->g = clamp(src->g, min_value, max_value);
+ dst->b = clamp(src->b, min_value, max_value);
+ dst->a = 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;
+ 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;
+ BOOL doClip, lighting;
+ 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 +3216,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;
/*
@@ -3156,11 +3277,37 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
TRACE("viewport x %.8e, y %.8e, width %.8e, height %.8e, min_z %.8e, max_z %.8e.\n",
vp.x, vp.y, vp.width, vp.height, vp.min_z, vp.max_z);
+ lighting = state->render_states[WINED3D_RS_LIGHTING]
+ && (dst_fvf & (WINED3DFVF_DIFFUSE | WINED3DFVF_SPECULAR));
+
multiply_matrix(&mat,&view_mat,&world_mat);
multiply_matrix(&mat,&proj_mat,&mat);
numTextures = (dst_fvf & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
+ if (lighting)
+ {
+ if (state->render_states[WINED3D_RS_COLORVERTEX])
+ {
+ diffuse_source = validate_material_colour_source(stream_info->use_map,
+ state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE]);
+ specular_source = validate_material_colour_source(stream_info->use_map,
+ state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]);
+ }
+ else
+ {
+ diffuse_source = specular_source = WINED3D_MCS_MATERIAL;
+ }
+ }
+ else
+ {
+ diffuse_source = WINED3D_MCS_COLOR1;
+ specular_source = WINED3D_MCS_COLOR2;
+ }
+ 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 +3425,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)
--
2.21.0
4
23
[PATCH 7/8] wined3d: Implement spot lights in process_vertices_strided().
by Henri Verbeet 20 May '19
by Henri Verbeet 20 May '19
20 May '19
From: Paul Gofman <gofmanp(a)gmail.com>
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/ddraw/tests/ddraw1.c | 26 ++++++++++++++++
dlls/wined3d/device.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 104 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index 5c9ccba63bf..ee0b1b431a7 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -6368,6 +6368,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),
@@ -6419,6 +6431,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},
@@ -6454,10 +6478,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 f5b9caadd28..33aba881cc6 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3296,6 +3296,10 @@ static void init_transformed_lights(struct lights_settings *ls,
++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 +3347,32 @@ static void init_transformed_lights(struct lights_settings *ls,
light->specular = light_info->OriginalParms.specular;
++index;
}
+
+ for (i = 0; i < light_count; ++i)
+ {
+ light_info = lights[i];
+ if (light_info->OriginalParms.type != WINED3D_LIGHT_SPOT)
+ continue;
+
+ light = &ls->lights[index];
+
+ wined3d_vec4_transform(&light->position, &light_info->position, &state->transforms[WINED3D_TS_VIEW]);
+ wined3d_vec4_transform(&vec4, &light_info->direction, &state->transforms[WINED3D_TS_VIEW]);
+ light->direction = *(struct wined3d_vec3 *)&vec4;
+ wined3d_vec3_normalise(&light->direction);
+ 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,
@@ -3442,6 +3472,54 @@ static void compute_light(struct wined3d_color *ambient, struct wined3d_color *d
&normal_transformed, &position_transformed_normalised, 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_normalise(&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_normalised, light, ls);
+ }
}
/* Context activation is done by the caller. */
--
2.11.0
1
0
[PATCH 6/8] wined3d: Implement point lights in process_vertices_strided().
by Henri Verbeet 20 May '19
by Henri Verbeet 20 May '19
20 May '19
From: Paul Gofman <gofmanp(a)gmail.com>
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/ddraw/tests/ddraw1.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++
dlls/wined3d/device.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 123 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index 22b43c42295..5c9ccba63bf 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -6356,6 +6356,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
{
@@ -6374,6 +6407,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},
@@ -6396,7 +6453,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 23aca23d24d..f5b9caadd28 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3292,6 +3292,10 @@ static void init_transformed_lights(struct lights_settings *ls,
++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;
@@ -3319,6 +3323,26 @@ static void init_transformed_lights(struct lights_settings *ls,
light->specular = light_info->OriginalParms.specular;
++index;
}
+
+ for (i = 0; i < light_count; ++i)
+ {
+ light_info = lights[i];
+ if (light_info->OriginalParms.type != WINED3D_LIGHT_POINT)
+ continue;
+
+ light = &ls->lights[index];
+
+ wined3d_vec4_transform(&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,
@@ -3353,7 +3377,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 att;
wined3d_vec4_transform(&position_transformed, position, &ls->modelview_matrix);
position_transformed_normalised = *(const struct wined3d_vec3 *)&position_transformed;
@@ -3381,6 +3407,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_normalised, 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_normalise(&dir);
+ update_light_diffuse_specular(diffuse, specular, &dir, att, material_shininess,
+ &normal_transformed, &position_transformed_normalised, light, ls);
+ }
+ }
}
/* Context activation is done by the caller. */
--
2.11.0
1
0
[PATCH 3/8] wined3d: Move multiply_vector_matrix() to wined3d_private.h.
by Henri Verbeet 20 May '19
by Henri Verbeet 20 May '19
20 May '19
From: Paul Gofman <gofmanp(a)gmail.com>
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
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 f85fb5a3e1d..baafaf8e3c3 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_transform(&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_transform(&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_transform(&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_transform(&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_transform(&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_transform(&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 87543f4a92e..a74a837c43b 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -4877,6 +4877,19 @@ static inline void wined3d_get_material_colour_source(enum wined3d_material_colo
*specular = validate_material_colour_source(si->use_map, state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]);
}
+static inline void wined3d_vec4_transform(struct wined3d_vec4 *dst,
+ const struct wined3d_vec4 *v, const struct wined3d_matrix *m)
+{
+ struct wined3d_vec4 tmp;
+
+ tmp.x = v->x * m->_11 + v->y * m->_21 + v->z * m->_31 + v->w * m->_41;
+ tmp.y = v->x * m->_12 + v->y * m->_22 + v->z * m->_32 + v->w * m->_42;
+ tmp.z = v->x * m->_13 + v->y * m->_23 + v->z * m->_33 + v->w * m->_43;
+ tmp.w = v->x * m->_14 + v->y * m->_24 + v->z * m->_34 + v->w * m->_44;
+
+ *dst = tmp;
+}
+
BOOL invert_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m) DECLSPEC_HIDDEN;
void compute_normal_matrix(float *normal_matrix, BOOL legacy_lighting,
--
2.11.0
1
0
[PATCH 2/8] wined3d: Use the correct colour sources in process_vertices_strided().
by Henri Verbeet 20 May '19
by Henri Verbeet 20 May '19
20 May '19
From: Paul Gofman <gofmanp(a)gmail.com>
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/device.c | 176 ++++++++++++++++++++++++++++++++++++++------------
1 file changed, 136 insertions(+), 40 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 5a94d03b9bb..8c77b3b590f 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3072,20 +3072,132 @@ static unsigned int wined3d_get_flexible_vertex_size(DWORD fvf)
return size;
}
+static void wined3d_format_get_colour(const struct wined3d_format *format,
+ const void *data, struct wined3d_color *colour)
+{
+ float *output = &colour->r;
+ const uint32_t *u32_data;
+ const uint16_t *u16_data;
+ const float *f32_data;
+ unsigned int i;
+
+ static const struct wined3d_color default_colour = {0.0f, 0.0f, 0.0f, 1.0f};
+ static unsigned int warned;
+
+ switch (format->id)
+ {
+ case WINED3DFMT_B8G8R8A8_UNORM:
+ u32_data = data;
+ wined3d_color_from_d3dcolor(colour, *u32_data);
+ break;
+
+ case WINED3DFMT_R8G8B8A8_UNORM:
+ u32_data = data;
+ colour->r = (*u32_data & 0xffu) / 255.0f;
+ colour->g = ((*u32_data >> 8) & 0xffu) / 255.0f;
+ colour->b = ((*u32_data >> 16) & 0xffu) / 255.0f;
+ colour->a = ((*u32_data >> 24) & 0xffu) / 255.0f;
+ break;
+
+ case WINED3DFMT_R16G16_UNORM:
+ case WINED3DFMT_R16G16B16A16_UNORM:
+ u16_data = data;
+ *colour = default_colour;
+ for (i = 0; i < format->component_count; ++i)
+ output[i] = u16_data[i] / 65535.0f;
+ break;
+
+ case WINED3DFMT_R32_FLOAT:
+ case WINED3DFMT_R32G32_FLOAT:
+ case WINED3DFMT_R32G32B32_FLOAT:
+ case WINED3DFMT_R32G32B32A32_FLOAT:
+ f32_data = data;
+ *colour = default_colour;
+ for (i = 0; i < format->component_count; ++i)
+ output[i] = f32_data[i];
+ break;
+
+ default:
+ *colour = default_colour;
+ if (!warned++)
+ FIXME("Unhandled colour format conversion, format %s.\n", debug_d3dformat(format->id));
+ break;
+ }
+}
+
+static void wined3d_colour_from_mcs(struct wined3d_color *colour, enum wined3d_material_color_source mcs,
+ const struct wined3d_color *material_colour, unsigned int index,
+ const struct wined3d_stream_info *stream_info)
+{
+ const struct wined3d_stream_info_element *element = NULL;
+
+ switch (mcs)
+ {
+ case WINED3D_MCS_MATERIAL:
+ *colour = *material_colour;
+ return;
+
+ case WINED3D_MCS_COLOR1:
+ if (!(stream_info->use_map & (1u << WINED3D_FFP_DIFFUSE)))
+ {
+ colour->r = colour->g = colour->b = colour->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)))
+ {
+ colour->r = colour->g = colour->b = 0.0f;
+ colour->a = 1.0f;
+ return;
+ }
+ element = &stream_info->elements[WINED3D_FFP_SPECULAR];
+ break;
+
+ default:
+ colour->r = colour->g = colour->b = colour->a = 0.0f;
+ ERR("Invalid material colour source %#x.\n", mcs);
+ return;
+ }
+
+ wined3d_format_get_colour(element->format, &element->data.addr[index * element->stride], colour);
+}
+
+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_colour;
struct wined3d_matrix mat, proj_mat, view_mat, world_mat;
+ const struct wined3d_state *state = &device->state;
+ const struct wined3d_format *output_colour_format;
+ static const struct wined3d_color black;
struct wined3d_map_desc map_desc;
struct wined3d_box box = {0};
struct wined3d_viewport vp;
+ unsigned int texture_count;
unsigned int vertex_size;
unsigned int i;
BYTE *dest_ptr;
BOOL doClip;
- DWORD numTextures;
HRESULT hr;
if (stream_info->use_map & (1u << WINED3D_FFP_NORMAL))
@@ -3095,11 +3207,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;
/*
@@ -3159,7 +3271,14 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
multiply_matrix(&mat,&view_mat,&world_mat);
multiply_matrix(&mat,&proj_mat,&mat);
- numTextures = (dst_fvf & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
+ texture_count = (dst_fvf & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
+
+ wined3d_get_material_colour_source(&diffuse_source, &emissive_source,
+ &ambient_source, &specular_source, state, stream_info);
+
+ output_colour_format = wined3d_get_format(device->adapter, WINED3DFMT_B8G8R8A8_UNORM, 0);
+ material_specular_state_colour = state->render_states[WINED3D_RS_SPECULARENABLE]
+ ? &state->material.specular : &black;
for (i = 0; i < dwCount; i+= 1) {
unsigned int tex_index;
@@ -3278,50 +3397,27 @@ 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;
- }
-
- *( (DWORD *) dest_ptr) = 0xffffffff;
- dest_ptr += sizeof(DWORD);
- }
- else
- {
- copy_and_next(dest_ptr, color_d, sizeof(DWORD));
- }
+ wined3d_colour_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_colour_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;
-
- if(!warned) {
- ERR("No specular color in source, but destination has one\n");
- warned = TRUE;
- }
+ struct wined3d_color material_specular;
- *(DWORD *)dest_ptr = 0xff000000;
- dest_ptr += sizeof(DWORD);
- }
- else
- {
- copy_and_next(dest_ptr, color_s, sizeof(DWORD));
- }
+ wined3d_colour_from_mcs(&material_specular, specular_source,
+ material_specular_state_colour, i, stream_info);
+ wined3d_color_clamp(&material_specular, &material_specular, 0.0f, 1.0f);
+ *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_colour_format, &material_specular);
+ dest_ptr += sizeof(DWORD);
}
- for (tex_index = 0; tex_index < numTextures; ++tex_index)
+ for (tex_index = 0; tex_index < texture_count; ++tex_index)
{
const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_TEXCOORD0 + tex_index];
const float *tex_coord = (const float *)(element->data.addr + i * element->stride);
--
2.11.0
1
0