wined3d: Light parameter fixes.
This commit is contained in:
parent
fb1469c47d
commit
76b7cac7af
|
@ -218,6 +218,65 @@ static void LightTest(void)
|
|||
/* Light 23 has not been set */
|
||||
rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
|
||||
ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
|
||||
|
||||
/* Set some lights with invalid parameters */
|
||||
memset(&light, 0, sizeof(D3DLIGHT7));
|
||||
light.dltType = 0;
|
||||
U1(light.dcvDiffuse).r = 1.f;
|
||||
U2(light.dcvDiffuse).g = 1.f;
|
||||
U3(light.dcvDiffuse).b = 1.f;
|
||||
U3(light.dvDirection).z = 1.f;
|
||||
rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
|
||||
ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
|
||||
|
||||
memset(&light, 0, sizeof(D3DLIGHT7));
|
||||
light.dltType = 12345;
|
||||
U1(light.dcvDiffuse).r = 1.f;
|
||||
U2(light.dcvDiffuse).g = 1.f;
|
||||
U3(light.dcvDiffuse).b = 1.f;
|
||||
U3(light.dvDirection).z = 1.f;
|
||||
rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
|
||||
ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
|
||||
|
||||
rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
|
||||
ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
|
||||
|
||||
memset(&light, 0, sizeof(D3DLIGHT7));
|
||||
light.dltType = D3DLIGHT_SPOT;
|
||||
U1(light.dcvDiffuse).r = 1.f;
|
||||
U2(light.dcvDiffuse).g = 1.f;
|
||||
U3(light.dcvDiffuse).b = 1.f;
|
||||
U3(light.dvDirection).z = 1.f;
|
||||
|
||||
U3(light.dvAttenuation0) = -1.0 / 0.0; /* -INFINITY */
|
||||
rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
|
||||
ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
|
||||
|
||||
U3(light.dvAttenuation0) = -1.0;
|
||||
rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
|
||||
ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
|
||||
|
||||
U3(light.dvAttenuation0) = 0.0;
|
||||
rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
|
||||
ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
|
||||
|
||||
U3(light.dvAttenuation0) = 1.0;
|
||||
rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
|
||||
ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
|
||||
|
||||
U3(light.dvAttenuation0) = 1.0 / 0.0; /* +INFINITY */
|
||||
rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
|
||||
ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
|
||||
|
||||
U3(light.dvAttenuation0) = 0.0 / 0.0; /* NaN */
|
||||
rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
|
||||
ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
|
||||
|
||||
/* Directional light ignores attenuation */
|
||||
light.dltType = D3DLIGHT_DIRECTIONAL;
|
||||
U3(light.dvAttenuation0) = -1.0;
|
||||
rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
|
||||
ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
|
||||
}
|
||||
|
||||
static void ProcessVerticesTest(void)
|
||||
|
|
|
@ -2199,6 +2199,37 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetLight(IWineD3DDevice *iface, DWORD I
|
|||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
TRACE("(%p) : Idx(%d), pLight(%p). Hash index is %d\n", This, Index, pLight, Hi);
|
||||
|
||||
/* Check the parameter range. Need for speed most wanted sets junk lights which confuse
|
||||
* the gl driver.
|
||||
*/
|
||||
if(!pLight) {
|
||||
WARN("Light pointer = NULL, returning WINED3DERR_INVALIDCALL\n");
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
switch(pLight->Type) {
|
||||
case WINED3DLIGHT_POINT:
|
||||
case WINED3DLIGHT_SPOT:
|
||||
case WINED3DLIGHT_PARALLELPOINT:
|
||||
case WINED3DLIGHT_GLSPOT:
|
||||
/* Incorrect attenuation values can cause the gl driver to crash. Happens with Need for speed
|
||||
* most wanted
|
||||
*/
|
||||
if(pLight->Attenuation0 < 0.0 || pLight->Attenuation1 < 0.0 || pLight->Attenuation2 < 0.0) {
|
||||
WARN("Attenuation is negative, returning WINED3DERR_INVALIDCALL\n");
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
break;
|
||||
|
||||
case WINED3DLIGHT_DIRECTIONAL:
|
||||
/* Ignores attenuation */
|
||||
break;
|
||||
|
||||
default:
|
||||
WARN("Light type out of range, returning WINED3DERR_INVALIDCALL\n");
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
LIST_FOR_EACH(e, &This->updateStateBlock->lightMap[Hi]) {
|
||||
object = LIST_ENTRY(e, PLIGHTINFOEL, entry);
|
||||
if(object->OriginalIndex == Index) break;
|
||||
|
|
|
@ -2981,21 +2981,16 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContex
|
|||
glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
|
||||
checkGLcall("glLightfv");
|
||||
|
||||
/* Attenuation - Are these right? guessing... */
|
||||
glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
|
||||
checkGLcall("glLightf");
|
||||
glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
|
||||
checkGLcall("glLightf");
|
||||
|
||||
if ((lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range) >= FLT_MIN) {
|
||||
quad_att = 1.4/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
|
||||
} else {
|
||||
quad_att = 0; /* 0 or MAX? (0 seems to be ok) */
|
||||
}
|
||||
|
||||
if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
|
||||
glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
|
||||
checkGLcall("glLightf");
|
||||
/* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
|
||||
* but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
|
||||
* Attenuation0 to NaN and crashes in the gl lib
|
||||
*/
|
||||
|
||||
switch (lightInfo->OriginalParms.Type) {
|
||||
case WINED3DLIGHT_POINT:
|
||||
|
@ -3004,6 +2999,14 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContex
|
|||
checkGLcall("glLightfv");
|
||||
glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
|
||||
checkGLcall("glLightf");
|
||||
/* Attenuation - Are these right? guessing... */
|
||||
glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
|
||||
checkGLcall("glLightf");
|
||||
glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
|
||||
checkGLcall("glLightf");
|
||||
if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
|
||||
glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
|
||||
checkGLcall("glLightf");
|
||||
/* FIXME: Range */
|
||||
break;
|
||||
|
||||
|
@ -3018,6 +3021,14 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContex
|
|||
checkGLcall("glLightf");
|
||||
glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
|
||||
checkGLcall("glLightf");
|
||||
/* Attenuation - Are these right? guessing... */
|
||||
glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
|
||||
checkGLcall("glLightf");
|
||||
glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
|
||||
checkGLcall("glLightf");
|
||||
if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
|
||||
glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
|
||||
checkGLcall("glLightf");
|
||||
/* FIXME: Range */
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue