Only reapply the world, view or projection transform changes if we

really have to.
This commit is contained in:
Jason Edmeades 2003-04-21 23:53:03 +00:00 committed by Alexandre Julliard
parent 9fdc759b90
commit e0d2fb6779
2 changed files with 90 additions and 53 deletions

View File

@ -258,6 +258,12 @@ struct IDirect3DDevice8Impl
float lightPosn[MAX_ACTIVE_LIGHTS][4]; float lightPosn[MAX_ACTIVE_LIGHTS][4];
float lightDirn[MAX_ACTIVE_LIGHTS][4]; float lightDirn[MAX_ACTIVE_LIGHTS][4];
/* Optimization */
D3DMATRIX lastProj;
D3DMATRIX lastView;
D3DMATRIX lastWorld0;
/* OpenGL related */ /* OpenGL related */
GLXContext glCtx; GLXContext glCtx;
XVisualInfo *visInfo; XVisualInfo *visInfo;

View File

@ -1700,6 +1700,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DT
D3DMATRIX m; D3DMATRIX m;
int k; int k;
float f; float f;
BOOL viewChanged = TRUE;
/* Most of this routine, comments included copied from ddraw tree initially: */ /* Most of this routine, comments included copied from ddraw tree initially: */
TRACE("(%p) : State=%d\n", This, d3dts); TRACE("(%p) : State=%d\n", This, d3dts);
@ -1760,7 +1761,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DT
case D3DTS_TEXTURE5: case D3DTS_TEXTURE5:
case D3DTS_TEXTURE6: case D3DTS_TEXTURE6:
case D3DTS_TEXTURE7: case D3DTS_TEXTURE7:
conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts]); conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts]);
FIXME("Unhandled transform state for TEXTURE%d!!!\n", d3dts - D3DTS_TEXTURE0); FIXME("Unhandled transform state for TEXTURE%d!!!\n", d3dts - D3DTS_TEXTURE0);
FIXME("must use glMatrixMode(GL_TEXTURE) before texturing\n"); FIXME("must use glMatrixMode(GL_TEXTURE) before texturing\n");
break; break;
@ -1776,47 +1777,59 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DT
/** store it */ /** store it */
conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts]); conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts]);
if (checkGLSupport(ARB_VERTEX_BLEND)) { if (checkGLSupport(ARB_VERTEX_BLEND)) {
FIXME("TODO\n"); FIXME("TODO\n");
} else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) { } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
FIXME("TODO\n"); FIXME("TODO\n");
} }
} }
/* /*
* Move the GL operation to outside of switch to make it work * Move the GL operation to outside of switch to make it work
* regardless of transform set order. Optimize later. * regardless of transform set order.
*/ */
ENTER_GL(); ENTER_GL();
glMatrixMode(GL_PROJECTION); if (memcmp(&This->lastProj, &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0], sizeof(D3DMATRIX))) {
checkGLcall("glMatrixMode"); glMatrixMode(GL_PROJECTION);
glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]); checkGLcall("glMatrixMode");
checkGLcall("glLoadMatrixf"); glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]);
checkGLcall("glLoadMatrixf");
memcpy(&This->lastProj, &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0], sizeof(D3DMATRIX));
} else {
TRACE("Skipping as projection already correct\n");
}
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
checkGLcall("glMatrixMode"); checkGLcall("glMatrixMode");
glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]); viewChanged = FALSE;
checkGLcall("glLoadMatrixf"); if (memcmp(&This->lastView, &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0], sizeof(D3DMATRIX))) {
glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
checkGLcall("glLoadMatrixf");
memcpy(&This->lastView, &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0], sizeof(D3DMATRIX));
viewChanged = TRUE;
/* If we are changing the View matrix, reset the light and clipping planes to the new view */ /* If we are changing the View matrix, reset the light and clipping planes to the new view */
if (d3dts == D3DTS_VIEW) { if (d3dts == D3DTS_VIEW) {
/* NOTE: We have to reset the positions even if the light/plane is not currently /* NOTE: We have to reset the positions even if the light/plane is not currently
enabled, since the call to enable it will not reset the position. */ enabled, since the call to enable it will not reset the position. */
/* Reset lights */ /* Reset lights */
for (k = 0; k < This->maxLights; k++) { for (k = 0; k < This->maxLights; k++) {
glLightfv(GL_LIGHT0 + k, GL_POSITION, &This->lightPosn[k][0]); glLightfv(GL_LIGHT0 + k, GL_POSITION, &This->lightPosn[k][0]);
checkGLcall("glLightfv posn"); checkGLcall("glLightfv posn");
glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, &This->lightDirn[k][0]); glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, &This->lightDirn[k][0]);
checkGLcall("glLightfv dirn"); checkGLcall("glLightfv dirn");
} }
/* Reset Clipping Planes if clipping is enabled */ /* Reset Clipping Planes if clipping is enabled */
for (k = 0; k < This->clipPlanes; k++) { for (k = 0; k < This->clipPlanes; k++) {
glClipPlane(GL_CLIP_PLANE0 + k, This->StateBlock->clipplane[k]); glClipPlane(GL_CLIP_PLANE0 + k, This->StateBlock->clipplane[k]);
checkGLcall("glClipPlane"); checkGLcall("glClipPlane");
} }
}
} else {
TRACE("Skipping view setup as view already correct\n");
} }
/** /**
@ -1826,47 +1839,65 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DT
switch (This->UpdateStateBlock->vertex_blend) { switch (This->UpdateStateBlock->vertex_blend) {
case D3DVBF_DISABLE: case D3DVBF_DISABLE:
{ {
glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]); if (viewChanged == TRUE ||
checkGLcall("glMultMatrixf"); (memcmp(&This->lastWorld0, &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0], sizeof(D3DMATRIX)))) {
memcpy(&This->lastWorld0, &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0], sizeof(D3DMATRIX));
if (viewChanged==FALSE) {
glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
checkGLcall("glLoadMatrixf");
}
glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
checkGLcall("glMultMatrixf");
} else {
TRACE("Skipping as world already correct\n");
}
} }
break; break;
case D3DVBF_1WEIGHTS: case D3DVBF_1WEIGHTS:
case D3DVBF_2WEIGHTS: case D3DVBF_2WEIGHTS:
case D3DVBF_3WEIGHTS: case D3DVBF_3WEIGHTS:
{ {
FIXME("valid/correct D3DVBF_[1..3]WEIGHTS\n"); FIXME("valid/correct D3DVBF_[1..3]WEIGHTS\n");
/* /*
* doc seems to say that the weight values must be in vertex data (specified in FVF by D3DFVF_XYZB*) * doc seems to say that the weight values must be in vertex data (specified in FVF by D3DFVF_XYZB*)
* so waiting for the values before matrix work * so waiting for the values before matrix work
for (k = 0; k < This->UpdateStateBlock->vertex_blend; ++k) { for (k = 0; k < This->UpdateStateBlock->vertex_blend; ++k) {
glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(k)].u.m[0][0]); glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(k)].u.m[0][0]);
checkGLcall("glMultMatrixf"); checkGLcall("glMultMatrixf");
} }
*/ */
} }
break; break;
case D3DVBF_TWEENING: case D3DVBF_TWEENING:
{ {
FIXME("valid/correct D3DVBF_TWEENING\n"); FIXME("valid/correct D3DVBF_TWEENING\n");
f = This->UpdateStateBlock->tween_factor; f = This->UpdateStateBlock->tween_factor;
m.u.s._11 = f; m.u.s._12 = f; m.u.s._13 = f; m.u.s._14 = f; m.u.s._11 = f; m.u.s._12 = f; m.u.s._13 = f; m.u.s._14 = f;
m.u.s._21 = f; m.u.s._22 = f; m.u.s._23 = f; m.u.s._24 = f; m.u.s._21 = f; m.u.s._22 = f; m.u.s._23 = f; m.u.s._24 = f;
m.u.s._31 = f; m.u.s._32 = f; m.u.s._33 = f; m.u.s._34 = f; m.u.s._31 = f; m.u.s._32 = f; m.u.s._33 = f; m.u.s._34 = f;
m.u.s._41 = f; m.u.s._42 = f; m.u.s._43 = f; m.u.s._44 = f; m.u.s._41 = f; m.u.s._42 = f; m.u.s._43 = f; m.u.s._44 = f;
glMultMatrixf((float *) &m.u.m[0][0]); if (viewChanged==FALSE) {
checkGLcall("glMultMatrixf"); glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
checkGLcall("glLoadMatrixf");
}
glMultMatrixf((float *) &m.u.m[0][0]);
checkGLcall("glMultMatrixf");
} }
break; break;
case D3DVBF_0WEIGHTS: case D3DVBF_0WEIGHTS:
{ {
FIXME("valid/correct D3DVBF_0WEIGHTS\n"); FIXME("valid/correct D3DVBF_0WEIGHTS\n");
/* single matrix of weight 1.0f */ /* single matrix of weight 1.0f */
m.u.s._11 = 1.0f; m.u.s._12 = 1.0f; m.u.s._13 = 1.0f; m.u.s._14 = 1.0f; m.u.s._11 = 1.0f; m.u.s._12 = 1.0f; m.u.s._13 = 1.0f; m.u.s._14 = 1.0f;
m.u.s._21 = 1.0f; m.u.s._22 = 1.0f; m.u.s._23 = 1.0f; m.u.s._24 = 1.0f; m.u.s._21 = 1.0f; m.u.s._22 = 1.0f; m.u.s._23 = 1.0f; m.u.s._24 = 1.0f;
m.u.s._31 = 1.0f; m.u.s._32 = 1.0f; m.u.s._33 = 1.0f; m.u.s._34 = 1.0f; m.u.s._31 = 1.0f; m.u.s._32 = 1.0f; m.u.s._33 = 1.0f; m.u.s._34 = 1.0f;
m.u.s._41 = 1.0f; m.u.s._42 = 1.0f; m.u.s._43 = 1.0f; m.u.s._44 = 1.0f; m.u.s._41 = 1.0f; m.u.s._42 = 1.0f; m.u.s._43 = 1.0f; m.u.s._44 = 1.0f;
glMultMatrixf((float *) &m.u.m[0][0]); if (viewChanged==FALSE) {
checkGLcall("glMultMatrixf"); glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
checkGLcall("glLoadMatrixf");
}
glMultMatrixf((float *) &m.u.m[0][0]);
checkGLcall("glMultMatrixf");
} }
break; break;
default: default: