wined3d: Move the world matrix to the state table.
This commit is contained in:
parent
20de200fa3
commit
5fa0f7f775
|
@ -1936,7 +1936,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR
|
|||
}
|
||||
|
||||
/* Initialize the current view state */
|
||||
This->modelview_valid = 1;
|
||||
This->proj_valid = 0;
|
||||
This->view_ident = 1;
|
||||
This->last_was_rhw = 0;
|
||||
|
@ -2364,13 +2363,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTransform(IWineD3DDevice *iface, W
|
|||
*/
|
||||
|
||||
/* Capture the times we can just ignore the change for now */
|
||||
if (d3dts == WINED3DTS_WORLDMATRIX(0)) {
|
||||
This->modelview_valid = FALSE;
|
||||
} else if (d3dts == WINED3DTS_VIEW) { /* handle the VIEW matrice */
|
||||
if (d3dts == WINED3DTS_VIEW) { /* handle the VIEW matrice */
|
||||
This->view_ident = !memcmp(lpmatrix, identity, 16 * sizeof(float));
|
||||
/* Handled by the state manager */
|
||||
} else { /* What was requested!?? */
|
||||
WARN("invalid matrix specified: %i\n", d3dts);
|
||||
}
|
||||
|
||||
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TRANSFORM(d3dts));
|
||||
|
|
|
@ -1813,6 +1813,29 @@ static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock) {
|
|||
}
|
||||
}
|
||||
|
||||
static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock) {
|
||||
/* Do not bother applying when we're in rhw mode. vertexdeclaration() will call
|
||||
* transform_world if it switches out of rhw mode. This function is also called
|
||||
* by transform_view below if the view matrix was changed
|
||||
*/
|
||||
if(stateblock->wineD3DDevice->last_was_rhw) {
|
||||
return;
|
||||
}
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
checkGLcall("glMatrixMode");
|
||||
|
||||
/* In the general case, the view matrix is the identity matrix */
|
||||
if (stateblock->wineD3DDevice->view_ident) {
|
||||
glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
|
||||
checkGLcall("glLoadMatrixf");
|
||||
} else {
|
||||
glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
|
||||
checkGLcall("glLoadMatrixf");
|
||||
glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
|
||||
checkGLcall("glMultMatrixf");
|
||||
}
|
||||
}
|
||||
|
||||
static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock) {
|
||||
unsigned int k;
|
||||
|
||||
|
@ -1823,12 +1846,9 @@ static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock) {
|
|||
*/
|
||||
|
||||
PLIGHTINFOEL *lightChain = NULL;
|
||||
stateblock->wineD3DDevice->modelview_valid = FALSE;
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
checkGLcall("glMatrixMode(GL_MODELVIEW)");
|
||||
glPushMatrix();
|
||||
checkGLcall("glPushMatrix()");
|
||||
glLoadMatrixf((float *)(float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
|
||||
checkGLcall("glLoadMatrixf(...)");
|
||||
|
||||
|
@ -1847,11 +1867,20 @@ static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock) {
|
|||
glClipPlane(GL_CLIP_PLANE0 + k, stateblock->clipplane[k]);
|
||||
checkGLcall("glClipPlane");
|
||||
}
|
||||
glPopMatrix();
|
||||
checkGLcall("glPopMatrix()");
|
||||
|
||||
/* Call the vdecl update. Will be tidied up later */
|
||||
StateTable[STATE_VDECL].apply(STATE_VDECL, stateblock);
|
||||
if(stateblock->wineD3DDevice->last_was_rhw) {
|
||||
glLoadIdentity();
|
||||
checkGLcall("glLoadIdentity()");
|
||||
/* No need to update the world matrix, the identity is fine */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
|
||||
* No need to do it here if the state is scheduled for update.
|
||||
*/
|
||||
if(!isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
|
||||
transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock);
|
||||
}
|
||||
}
|
||||
|
||||
static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateBlock) {
|
||||
|
@ -1869,9 +1898,10 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock) {
|
|||
BOOL transformed, lit;
|
||||
/* Some stuff is in the device until we have per context tracking */
|
||||
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
|
||||
BOOL wasrhw = device->last_was_rhw;
|
||||
|
||||
device->streamFixedUp = FALSE;
|
||||
|
||||
|
||||
/* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
|
||||
* here simply check whether a shader was set, or the user disabled shaders
|
||||
*/
|
||||
|
@ -1945,22 +1975,20 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock) {
|
|||
} else {
|
||||
|
||||
/* Untransformed, so relies on the view and projection matrices */
|
||||
device->last_was_rhw = FALSE;
|
||||
/* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
|
||||
device->untransformed = TRUE;
|
||||
|
||||
if (!useVertexShaderFunction) {
|
||||
device->modelview_valid = TRUE;
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
checkGLcall("glMatrixMode");
|
||||
|
||||
/* In the general case, the view matrix is the identity matrix */
|
||||
if (device->view_ident) {
|
||||
glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
|
||||
checkGLcall("glLoadMatrixf");
|
||||
} else {
|
||||
glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
|
||||
checkGLcall("glLoadMatrixf");
|
||||
glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
|
||||
checkGLcall("glMultMatrixf");
|
||||
/* Don't bother checking for !useVertexShaderFunction here. If shaders are always on wasrhw will never
|
||||
* be true. If they are switched on and off then knowing that the fixed function matrices are ok makes
|
||||
* those switches cheaper
|
||||
*/
|
||||
if (wasrhw) {
|
||||
/* switching out of orthogonal mode? have to reapply the modelview matrix.
|
||||
* Only do that when it is not dirty though
|
||||
*/
|
||||
if(!isStateDirty(device, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
|
||||
transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2763,7 +2791,7 @@ const struct StateEntry StateTable[] =
|
|||
{ /*254, undefined */ 0, state_undefined },
|
||||
{ /*255, undefined */ 0, state_undefined },
|
||||
/* End huge gap */
|
||||
{ /*256, WINED3DTS_WORLDMATRIX(0) */ STATE_VDECL, vertexdeclaration },
|
||||
{ /*256, WINED3DTS_WORLDMATRIX(0) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), transform_world },
|
||||
{ /*257, WINED3DTS_WORLDMATRIX(1) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(1)), transform_worldex },
|
||||
{ /*258, WINED3DTS_WORLDMATRIX(2) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(2)), transform_worldex },
|
||||
{ /*259, WINED3DTS_WORLDMATRIX(3) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(3)), transform_worldex },
|
||||
|
|
|
@ -1150,6 +1150,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
|
|||
we want to draw at screen position 0,0 - Set up ortho (rhw) mode as
|
||||
per drawprim (and leave set - it will sort itself out due to last_was_rhw */
|
||||
d3ddevice_set_ortho(This->resource.wineD3DDevice);
|
||||
IWineD3DDeviceImpl_MarkStateDirty(myDevice, STATE_VDECL);
|
||||
|
||||
if (iface == implSwapChain->frontBuffer) {
|
||||
glDrawBuffer(GL_FRONT);
|
||||
|
@ -2473,6 +2474,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
|
|||
/* Draw a textured quad
|
||||
*/
|
||||
d3ddevice_set_ortho(This->resource.wineD3DDevice);
|
||||
IWineD3DDeviceImpl_MarkStateDirty(myDevice, STATE_VDECL);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
|
|
|
@ -563,7 +563,6 @@ typedef struct IWineD3DDeviceImpl
|
|||
const shader_backend_t *shader_backend;
|
||||
|
||||
/* Optimization */
|
||||
BOOL modelview_valid;
|
||||
BOOL proj_valid;
|
||||
BOOL view_ident; /* true iff view matrix is identity */
|
||||
BOOL last_was_rhw; /* true iff last draw_primitive was in xyzrhw mode */
|
||||
|
|
Loading…
Reference in New Issue