wined3d: Move lights to the state table.

This commit is contained in:
Stefan Dösinger 2007-02-14 17:48:52 +01:00 committed by Alexandre Julliard
parent acadf3f241
commit 174b6321eb
3 changed files with 120 additions and 108 deletions

View File

@ -148,103 +148,6 @@ static void set_depth_stencil_fbo(IWineD3DDevice *iface, IWineD3DSurface *depth_
**********************************************************/
const float identity[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1}; /* When needed for comparisons */
/**********************************************************
* Utility functions follow
**********************************************************/
/* Convert the WINED3DLIGHT properties into equivalent gl lights */
static void setup_light(IWineD3DDevice *iface, LONG Index, PLIGHTINFOEL *lightInfo) {
float quad_att;
float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
/* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadMatrixf((float *)&This->stateBlock->transforms[WINED3DTS_VIEW].u.m[0][0]);
/* Diffuse: */
colRGBA[0] = lightInfo->OriginalParms.Diffuse.r;
colRGBA[1] = lightInfo->OriginalParms.Diffuse.g;
colRGBA[2] = lightInfo->OriginalParms.Diffuse.b;
colRGBA[3] = lightInfo->OriginalParms.Diffuse.a;
glLightfv(GL_LIGHT0+Index, GL_DIFFUSE, colRGBA);
checkGLcall("glLightfv");
/* Specular */
colRGBA[0] = lightInfo->OriginalParms.Specular.r;
colRGBA[1] = lightInfo->OriginalParms.Specular.g;
colRGBA[2] = lightInfo->OriginalParms.Specular.b;
colRGBA[3] = lightInfo->OriginalParms.Specular.a;
glLightfv(GL_LIGHT0+Index, GL_SPECULAR, colRGBA);
checkGLcall("glLightfv");
/* Ambient */
colRGBA[0] = lightInfo->OriginalParms.Ambient.r;
colRGBA[1] = lightInfo->OriginalParms.Ambient.g;
colRGBA[2] = lightInfo->OriginalParms.Ambient.b;
colRGBA[3] = lightInfo->OriginalParms.Ambient.a;
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");
switch (lightInfo->OriginalParms.Type) {
case WINED3DLIGHT_POINT:
/* Position */
glLightfv(GL_LIGHT0+Index, GL_POSITION, &lightInfo->lightPosn[0]);
checkGLcall("glLightfv");
glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
checkGLcall("glLightf");
/* FIXME: Range */
break;
case WINED3DLIGHT_SPOT:
/* Position */
glLightfv(GL_LIGHT0+Index, GL_POSITION, &lightInfo->lightPosn[0]);
checkGLcall("glLightfv");
/* Direction */
glLightfv(GL_LIGHT0+Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
checkGLcall("glLightfv");
glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
checkGLcall("glLightf");
glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
checkGLcall("glLightf");
/* FIXME: Range */
break;
case WINED3DLIGHT_DIRECTIONAL:
/* Direction */
glLightfv(GL_LIGHT0+Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
checkGLcall("glLightfv");
glLightf(GL_LIGHT0+Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
checkGLcall("glLightf");
glLightf(GL_LIGHT0+Index, GL_SPOT_EXPONENT, 0.0f);
checkGLcall("glLightf");
break;
default:
FIXME("Unrecognized light type %d\n", lightInfo->OriginalParms.Type);
}
/* Restore the modelview matrix */
glPopMatrix();
}
/**********************************************************
* GLSL helper functions follow
**********************************************************/
@ -2423,7 +2326,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetLight(IWineD3DDevice *iface, DWORD I
/* Update the live definitions if the light is currently assigned a glIndex */
if (object->glIndex != -1 && !This->isRecordingState) {
setup_light(iface, object->glIndex, object);
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_ACTIVELIGHT(object->glIndex));
}
return WINED3D_OK;
}
@ -2493,10 +2396,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetLightEnable(IWineD3DDevice *iface, D
if(!Enable) {
if(lightInfo->glIndex != -1) {
if(!This->isRecordingState) {
ENTER_GL();
glDisable(GL_LIGHT0 + lightInfo->glIndex);
checkGLcall("glDisable GL_LIGHT0+Index");
LEAVE_GL();
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_ACTIVELIGHT(lightInfo->glIndex));
}
This->stateBlock->activeLights[lightInfo->glIndex] = NULL;
@ -2525,11 +2425,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetLightEnable(IWineD3DDevice *iface, D
/* i == lightInfo->glIndex */
if(!This->isRecordingState) {
setup_light(iface, i, lightInfo);
ENTER_GL();
glEnable(GL_LIGHT0 + i);
checkGLcall("glEnable(GL_LIGHT0 + i)");
LEAVE_GL();
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_ACTIVELIGHT(i));
}
}
}

View File

@ -2783,6 +2783,110 @@ static void viewport(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCon
}
static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
UINT Index = state - STATE_ACTIVELIGHT(0);
PLIGHTINFOEL *lightInfo = stateblock->activeLights[Index];
if(!lightInfo) {
glDisable(GL_LIGHT0 + Index);
checkGLcall("glDisable(GL_LIGHT0 + Index)");
} else {
float quad_att;
float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
/* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadMatrixf((float *)&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
/* Diffuse: */
colRGBA[0] = lightInfo->OriginalParms.Diffuse.r;
colRGBA[1] = lightInfo->OriginalParms.Diffuse.g;
colRGBA[2] = lightInfo->OriginalParms.Diffuse.b;
colRGBA[3] = lightInfo->OriginalParms.Diffuse.a;
glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
checkGLcall("glLightfv");
/* Specular */
colRGBA[0] = lightInfo->OriginalParms.Specular.r;
colRGBA[1] = lightInfo->OriginalParms.Specular.g;
colRGBA[2] = lightInfo->OriginalParms.Specular.b;
colRGBA[3] = lightInfo->OriginalParms.Specular.a;
glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
checkGLcall("glLightfv");
/* Ambient */
colRGBA[0] = lightInfo->OriginalParms.Ambient.r;
colRGBA[1] = lightInfo->OriginalParms.Ambient.g;
colRGBA[2] = lightInfo->OriginalParms.Ambient.b;
colRGBA[3] = lightInfo->OriginalParms.Ambient.a;
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");
switch (lightInfo->OriginalParms.Type) {
case WINED3DLIGHT_POINT:
/* Position */
glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
checkGLcall("glLightfv");
glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
checkGLcall("glLightf");
/* FIXME: Range */
break;
case WINED3DLIGHT_SPOT:
/* Position */
glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
checkGLcall("glLightfv");
/* Direction */
glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
checkGLcall("glLightfv");
glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
checkGLcall("glLightf");
glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
checkGLcall("glLightf");
/* FIXME: Range */
break;
case WINED3DLIGHT_DIRECTIONAL:
/* Direction */
glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
checkGLcall("glLightfv");
glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
checkGLcall("glLightf");
glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
checkGLcall("glLightf");
break;
default:
FIXME("Unrecognized light type %d\n", lightInfo->OriginalParms.Type);
}
/* Restore the modelview matrix */
glPopMatrix();
glEnable(GL_LIGHT0 + Index);
checkGLcall("glEnable(GL_LIGHT0 + Index)");
}
return;
}
const struct StateEntry StateTable[] =
{
/* State name representative, apply function */
@ -3803,4 +3907,13 @@ const struct StateEntry StateTable[] =
{ /* , STATE_VIEWPORT */ STATE_VIEWPORT, viewport },
{ /* , STATE_VERTEXSHADERCONSTANT */ STATE_VERTEXSHADERCONSTANT, shaderconstant },
{ /* , STATE_PIXELSHADERCONSTANT */ STATE_VERTEXSHADERCONSTANT, shaderconstant },
/* Lights */
{ /* , STATE_ACTIVELIGHT(0) */ STATE_ACTIVELIGHT(0), light },
{ /* , STATE_ACTIVELIGHT(1) */ STATE_ACTIVELIGHT(1), light },
{ /* , STATE_ACTIVELIGHT(2) */ STATE_ACTIVELIGHT(2), light },
{ /* , STATE_ACTIVELIGHT(3) */ STATE_ACTIVELIGHT(3), light },
{ /* , STATE_ACTIVELIGHT(4) */ STATE_ACTIVELIGHT(4), light },
{ /* , STATE_ACTIVELIGHT(5) */ STATE_ACTIVELIGHT(5), light },
{ /* , STATE_ACTIVELIGHT(6) */ STATE_ACTIVELIGHT(6), light },
{ /* , STATE_ACTIVELIGHT(7) */ STATE_ACTIVELIGHT(7), light },
};

View File

@ -441,7 +441,10 @@ typedef void (*APPLYSTATEFUNC)(DWORD state, IWineD3DStateBlockImpl *stateblock,
#define STATE_IS_VERTEXSHADERCONSTANT(a) ((a) == STATE_VERTEXSHADERCONSTANT)
#define STATE_IS_PIXELSHADERCONSTANT(a) ((a) == STATE_PIXELSHADERCONSTANT)
#define STATE_HIGHEST (STATE_PIXELSHADERCONSTANT)
#define STATE_ACTIVELIGHT(a) (STATE_PIXELSHADERCONSTANT + (a) + 1)
#define STATE_IS_ACTIVELIGHT(a) ((a) >= STATE_ACTIVELIGHT(0) && (a) < STATE_PIXELSHADERCONSTANT(MAX_ACTIVE_LIGHTS))
#define STATE_HIGHEST (STATE_ACTIVELIGHT(MAX_ACTIVE_LIGHTS - 1))
struct StateEntry
{