Add fps debug channel, so we can see how the d3d code is performing and
their impact of performance changes. SetTransform almost rewritten in a much neater way, and in coordination with drawprim it significantly reduces the number of times that we reload the matrixes.
This commit is contained in:
parent
0a002212c1
commit
564f5828b0
|
@ -326,10 +326,11 @@ struct IDirect3DDevice8Impl
|
|||
UINT currentPalette;
|
||||
|
||||
/* Optimization */
|
||||
D3DMATRIX lastProj;
|
||||
D3DMATRIX lastView;
|
||||
D3DMATRIX lastWorld0;
|
||||
D3DMATRIX lastTexTrans[8];
|
||||
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 */
|
||||
|
||||
|
||||
/* OpenGL related */
|
||||
GLXContext glCtx;
|
||||
|
|
|
@ -40,11 +40,13 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(fps);
|
||||
|
||||
IDirect3DVertexShaderImpl* VertexShaders[64];
|
||||
IDirect3DVertexShaderDeclarationImpl* VertexShaderDeclarations[64];
|
||||
IDirect3DPixelShaderImpl* PixelShaders[64];
|
||||
|
||||
/* Debugging aids: */
|
||||
#ifdef FRAME_DEBUGGING
|
||||
BOOL isOn = FALSE;
|
||||
BOOL isDumpingFrames = FALSE;
|
||||
|
@ -109,6 +111,47 @@ void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
|
|||
TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
|
||||
}
|
||||
|
||||
/* Setup this textures matrix */
|
||||
static void set_texture_matrix(float *smat, DWORD flags)
|
||||
{
|
||||
float mat[16];
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
|
||||
if (flags == D3DTTFF_DISABLE) {
|
||||
glLoadIdentity();
|
||||
checkGLcall("glLoadIdentity()");
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags == (D3DTTFF_COUNT1|D3DTTFF_PROJECTED)) {
|
||||
ERR("Invalid texture transform flags: D3DTTFF_COUNT1|D3DTTFF_PROJECTED\n");
|
||||
checkGLcall("glLoadIdentity()");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(mat, smat, 16*sizeof(float));
|
||||
|
||||
switch (flags & ~D3DTTFF_PROJECTED) {
|
||||
case D3DTTFF_COUNT1: mat[1] = mat[5] = mat[9] = mat[13] = 0;
|
||||
case D3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
|
||||
default: mat[3] = mat[7] = mat[11] = 0, mat[15] = 1;
|
||||
}
|
||||
|
||||
if (flags & D3DTTFF_PROJECTED) switch (flags & ~D3DTTFF_PROJECTED) {
|
||||
case D3DTTFF_COUNT2:
|
||||
mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
|
||||
mat[1] = mat[5] = mat[9] = mat[13] = 0;
|
||||
break;
|
||||
case D3DTTFF_COUNT3:
|
||||
mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
|
||||
mat[2] = mat[6] = mat[10] = mat[14] = 0;
|
||||
break;
|
||||
}
|
||||
glLoadMatrixf(mat);
|
||||
checkGLcall("glLoadMatrixf(mat)");
|
||||
}
|
||||
|
||||
/* IDirect3D IUnknown parts follow: */
|
||||
HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
|
||||
{
|
||||
|
@ -322,6 +365,21 @@ HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST REC
|
|||
/* Dont call checkGLcall, as glGetError is not applicable here */
|
||||
TRACE("glXSwapBuffers called, Starting new frame\n");
|
||||
|
||||
/* FPS support */
|
||||
if (TRACE_ON(fps))
|
||||
{
|
||||
static long prev_time, frames;
|
||||
|
||||
DWORD time = GetTickCount();
|
||||
frames++;
|
||||
/* every 1.5 seconds */
|
||||
if (time - prev_time > 1500) {
|
||||
TRACE_(fps)("@@@ %.2ffps\n", 1000.0*frames/(time - prev_time));
|
||||
prev_time = time;
|
||||
frames = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(FRAME_DEBUGGING)
|
||||
{
|
||||
if (GetFileAttributesA("C:\\D3DTRACE") != INVALID_FILE_ATTRIBUTES) {
|
||||
|
@ -1244,268 +1302,110 @@ HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count
|
|||
}
|
||||
HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE d3dts, CONST D3DMATRIX* lpmatrix) {
|
||||
ICOM_THIS(IDirect3DDevice8Impl,iface);
|
||||
D3DMATRIX m;
|
||||
int k;
|
||||
float f;
|
||||
BOOL viewChanged = TRUE;
|
||||
int Stage;
|
||||
|
||||
/* Most of this routine, comments included copied from ddraw tree initially: */
|
||||
TRACE("(%p) : State=%d\n", This, d3dts);
|
||||
|
||||
This->UpdateStateBlock->Changed.transform[d3dts] = TRUE;
|
||||
This->UpdateStateBlock->Set.transform[d3dts] = TRUE;
|
||||
memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX));
|
||||
|
||||
/* Handle recording of state blocks */
|
||||
if (This->isRecordingState) {
|
||||
TRACE("Recording... not performing anything\n");
|
||||
This->UpdateStateBlock->Changed.transform[d3dts] = TRUE;
|
||||
This->UpdateStateBlock->Set.transform[d3dts] = TRUE;
|
||||
memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX));
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
|
||||
|
||||
where ViewMat = Camera space, WorldMat = world space.
|
||||
|
||||
In OpenGL, camera and world space is combined into GL_MODELVIEW
|
||||
matrix. The Projection matrix stay projection matrix. */
|
||||
|
||||
/* After reading through both OpenGL and Direct3D documentations, I
|
||||
thought that D3D matrices were written in 'line major mode' transposed
|
||||
from OpenGL's 'column major mode'. But I found out that a simple memcpy
|
||||
works fine to transfer one matrix format to the other (it did not work
|
||||
when transposing)....
|
||||
|
||||
So :
|
||||
1) are the documentations wrong
|
||||
2) does the matrix work even if they are not read correctly
|
||||
3) is Mesa's implementation of OpenGL not compliant regarding Matrix
|
||||
loading using glLoadMatrix ?
|
||||
|
||||
Anyway, I always use 'conv_mat' to transfer the matrices from one format
|
||||
to the other so that if I ever find out that I need to transpose them, I
|
||||
will able to do it quickly, only by changing the macro conv_mat. */
|
||||
|
||||
if (d3dts < 256) {
|
||||
switch (d3dts) {
|
||||
case D3DTS_VIEW:
|
||||
conv_mat(lpmatrix, &This->StateBlock->transforms[D3DTS_VIEW]);
|
||||
break;
|
||||
|
||||
case D3DTS_PROJECTION:
|
||||
conv_mat(lpmatrix, &This->StateBlock->transforms[D3DTS_PROJECTION]);
|
||||
break;
|
||||
|
||||
case D3DTS_TEXTURE0:
|
||||
case D3DTS_TEXTURE1:
|
||||
case D3DTS_TEXTURE2:
|
||||
case D3DTS_TEXTURE3:
|
||||
case D3DTS_TEXTURE4:
|
||||
case D3DTS_TEXTURE5:
|
||||
case D3DTS_TEXTURE6:
|
||||
case D3DTS_TEXTURE7:
|
||||
conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts]);
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unhandled transform state!!\n");
|
||||
break;
|
||||
}
|
||||
* if the new matrix is the same as the current one,
|
||||
* we cut off any further processing. this seems to be a reasonable
|
||||
* optimization because as was noticed, some apps (warcraft3 for example)
|
||||
* tend towards setting the same matrix repeatedly for some dumb reason.
|
||||
*
|
||||
* From here on we assume that the new matrix is different, wherever it matters
|
||||
* but note
|
||||
*/
|
||||
if (!memcmp(&This->StateBlock->transforms[d3dts].u.m[0][0], lpmatrix, sizeof(D3DMATRIX))) {
|
||||
TRACE("The app is setting the same matrix over again\n");
|
||||
return D3D_OK;
|
||||
} else {
|
||||
/**
|
||||
* Indexed Vertex Blending Matrices 256 -> 511
|
||||
* where WORLDMATRIX(0) == 256!
|
||||
*/
|
||||
/** store it */
|
||||
conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts]);
|
||||
#if 0
|
||||
if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
|
||||
FIXME("TODO\n");
|
||||
} else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
|
||||
FIXME("TODO\n");
|
||||
}
|
||||
#endif
|
||||
conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts].u.m[0][0]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the GL operation to outside of switch to make it work
|
||||
* regardless of transform set order.
|
||||
ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
|
||||
where ViewMat = Camera space, WorldMat = world space.
|
||||
|
||||
In OpenGL, camera and world space is combined into GL_MODELVIEW
|
||||
matrix. The Projection matrix stay projection matrix.
|
||||
*/
|
||||
|
||||
/* Capture the times we can just ignore the change */
|
||||
if (d3dts == D3DTS_WORLDMATRIX(0)) {
|
||||
This->modelview_valid = FALSE;
|
||||
return D3D_OK;
|
||||
|
||||
} else if (d3dts == D3DTS_PROJECTION) {
|
||||
This->proj_valid = FALSE;
|
||||
return D3D_OK;
|
||||
|
||||
} else if (d3dts >= D3DTS_WORLDMATRIX(1) && d3dts <= D3DTS_WORLDMATRIX(255)) { /* Indexed Vertex Blending Matrices 256 -> 511 */
|
||||
/* Use arb_vertex_blend or NV_VERTEX_WEIGHTING? */
|
||||
FIXME("D3DTS_WORLDMATRIX(1..255) not handled\n");
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
/* Chances are we really are going to have to change a matrix */
|
||||
ENTER_GL();
|
||||
if (memcmp(&This->lastProj, &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0], sizeof(D3DMATRIX))) {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
checkGLcall("glMatrixMode");
|
||||
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);
|
||||
checkGLcall("glMatrixMode");
|
||||
viewChanged = FALSE;
|
||||
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 (d3dts == D3DTS_VIEW) {
|
||||
|
||||
/* 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. */
|
||||
|
||||
/* Reset lights */
|
||||
for (k = 0; k < GL_LIMITS(lights); k++) {
|
||||
glLightfv(GL_LIGHT0 + k, GL_POSITION, &This->lightPosn[k][0]);
|
||||
checkGLcall("glLightfv posn");
|
||||
glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, &This->lightDirn[k][0]);
|
||||
checkGLcall("glLightfv dirn");
|
||||
}
|
||||
|
||||
/* Reset Clipping Planes if clipping is enabled */
|
||||
for (k = 0; k < GL_LIMITS(clipplanes); k++) {
|
||||
glClipPlane(GL_CLIP_PLANE0 + k, This->StateBlock->clipplane[k]);
|
||||
checkGLcall("glClipPlane");
|
||||
}
|
||||
|
||||
/* Reapply texture transforms as based off modelview when applied */
|
||||
for (Stage = 0; Stage < GL_LIMITS(textures); Stage++) {
|
||||
|
||||
/* Only applicable if the transforms are not disabled */
|
||||
if (This->UpdateStateBlock->texture_state[Stage][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE)
|
||||
{
|
||||
/* Now apply texture transforms if not applying to the dummy textures */
|
||||
if (d3dts >= D3DTS_TEXTURE0 && d3dts <= D3DTS_TEXTURE7) { /* handle texture matrices */
|
||||
if (d3dts < GL_LIMITS(textures)) {
|
||||
int tex = d3dts - D3DTS_TEXTURE0;
|
||||
#if defined(GL_VERSION_1_3)
|
||||
glActiveTexture(GL_TEXTURE0 + Stage);
|
||||
glActiveTexture(GL_TEXTURE0 + tex);
|
||||
#else
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + tex);
|
||||
#endif
|
||||
checkGLcall("glActiveTexture(GL_TEXTURE0 + Stage);");
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
|
||||
glLoadIdentity();
|
||||
} else {
|
||||
D3DMATRIX fred;
|
||||
conv_mat(&This->StateBlock->transforms[D3DTS_TEXTURE0+Stage], &fred);
|
||||
glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_TEXTURE0+Stage].u.m[0][0]);
|
||||
}
|
||||
}
|
||||
checkGLcall("Load matrix for texture");
|
||||
}
|
||||
glMatrixMode(GL_MODELVIEW); /* Always leave in model view */
|
||||
}
|
||||
} else if ((d3dts >= D3DTS_TEXTURE0 && d3dts <= D3DTS_TEXTURE7) &&
|
||||
(This->UpdateStateBlock->texture_state[d3dts - D3DTS_TEXTURE0][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE)) {
|
||||
/* Now apply texture transforms if not applying to the dummy textures */
|
||||
Stage = d3dts - D3DTS_TEXTURE0;
|
||||
|
||||
if (memcmp(&This->lastTexTrans[Stage], &This->StateBlock->transforms[D3DTS_TEXTURE0 + Stage].u.m[0][0], sizeof(D3DMATRIX))) {
|
||||
memcpy(&This->lastTexTrans[Stage], &This->StateBlock->transforms[D3DTS_TEXTURE0 + Stage].u.m[0][0], sizeof(D3DMATRIX));
|
||||
|
||||
#if defined(GL_VERSION_1_3)
|
||||
glActiveTexture(GL_TEXTURE0 + Stage);
|
||||
#else
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
|
||||
#endif
|
||||
checkGLcall("glActiveTexture(GL_TEXTURE0 + Stage)");
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
|
||||
glLoadIdentity();
|
||||
} else {
|
||||
D3DMATRIX fred;
|
||||
conv_mat(&This->StateBlock->transforms[D3DTS_TEXTURE0+Stage], &fred);
|
||||
glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_TEXTURE0+Stage].u.m[0][0]);
|
||||
}
|
||||
checkGLcall("Load matrix for texture");
|
||||
glMatrixMode(GL_MODELVIEW); /* Always leave in model view */
|
||||
} else {
|
||||
TRACE("Skipping texture transform as already correct\n");
|
||||
set_texture_matrix((float *)lpmatrix, This->UpdateStateBlock->texture_state[tex][D3DTSS_TEXTURETRANSFORMFLAGS]);
|
||||
}
|
||||
|
||||
} else {
|
||||
TRACE("Skipping view setup as view already correct\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Vertex Blending as described
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/d3d/enums/d3dvertexblendflags.asp
|
||||
*/
|
||||
switch (This->UpdateStateBlock->vertex_blend) {
|
||||
case D3DVBF_DISABLE:
|
||||
{
|
||||
if (viewChanged == TRUE ||
|
||||
(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;
|
||||
case D3DVBF_1WEIGHTS:
|
||||
case D3DVBF_2WEIGHTS:
|
||||
case D3DVBF_3WEIGHTS:
|
||||
{
|
||||
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*)
|
||||
* so waiting for the values before matrix work
|
||||
for (k = 0; k < This->UpdateStateBlock->vertex_blend; ++k) {
|
||||
glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(k)].u.m[0][0]);
|
||||
checkGLcall("glMultMatrixf");
|
||||
}
|
||||
*/
|
||||
}
|
||||
break;
|
||||
case D3DVBF_TWEENING:
|
||||
{
|
||||
FIXME("valid/correct D3DVBF_TWEENING\n");
|
||||
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._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._41 = f; m.u.s._42 = f; m.u.s._43 = f; m.u.s._44 = f;
|
||||
if (viewChanged == FALSE) {
|
||||
glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
|
||||
checkGLcall("glLoadMatrixf");
|
||||
}
|
||||
glMultMatrixf((float *) &m.u.m[0][0]);
|
||||
checkGLcall("glMultMatrixf");
|
||||
}
|
||||
break;
|
||||
case D3DVBF_0WEIGHTS:
|
||||
{
|
||||
FIXME("valid/correct D3DVBF_0WEIGHTS\n");
|
||||
/* 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._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._41 = 1.0f; m.u.s._42 = 1.0f; m.u.s._43 = 1.0f; m.u.s._44 = 1.0f;
|
||||
if (viewChanged == FALSE) {
|
||||
glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
|
||||
checkGLcall("glLoadMatrixf");
|
||||
}
|
||||
glMultMatrixf((float *) &m.u.m[0][0]);
|
||||
checkGLcall("glMultMatrixf");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break; /* stupid compilator */
|
||||
} else if (d3dts == D3DTS_VIEW) { /* handle the VIEW matrice */
|
||||
float identity[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
|
||||
This->modelview_valid = FALSE;
|
||||
This->view_ident = !memcmp(lpmatrix, identity, 16*sizeof(float));
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
checkGLcall("glMatrixMode(GL_MODELVIEW)");
|
||||
glPushMatrix();
|
||||
glLoadMatrixf((float *)lpmatrix);
|
||||
checkGLcall("glLoadMatrixf(...)");
|
||||
|
||||
/* If we are changing the View matrix, reset the light and clipping planes to the new view
|
||||
* 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.
|
||||
* NOTE2: Apparently texture transforms do NOT need reapplying
|
||||
*/
|
||||
|
||||
/* Reset lights */
|
||||
for (k = 0; k < GL_LIMITS(lights); k++) {
|
||||
glLightfv(GL_LIGHT0 + k, GL_POSITION, This->lightPosn[k]);
|
||||
checkGLcall("glLightfv posn");
|
||||
glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, This->lightDirn[k]);
|
||||
checkGLcall("glLightfv dirn");
|
||||
}
|
||||
/* Reset Clipping Planes if clipping is enabled */
|
||||
for (k = 0; k < GL_LIMITS(clipplanes); k++) {
|
||||
glClipPlane(GL_CLIP_PLANE0 + k, This->StateBlock->clipplane[k]);
|
||||
checkGLcall("glClipPlane");
|
||||
}
|
||||
glPopMatrix();
|
||||
|
||||
} else { /* What was requested!?? */
|
||||
WARN("invalid matrix specified: %i\n", d3dts);
|
||||
|
||||
}
|
||||
|
||||
/* Release lock, all done */
|
||||
LEAVE_GL();
|
||||
|
||||
return D3D_OK;
|
||||
|
||||
}
|
||||
|
@ -1887,9 +1787,9 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWOR
|
|||
This->UpdateStateBlock->clipplane[Index][2],
|
||||
This->UpdateStateBlock->clipplane[Index][3]);
|
||||
glClipPlane(GL_CLIP_PLANE0 + Index, This->UpdateStateBlock->clipplane[Index]);
|
||||
checkGLcall("glClipPlane");
|
||||
|
||||
glPopMatrix();
|
||||
checkGLcall("glClipPlane");
|
||||
|
||||
LEAVE_GL();
|
||||
|
||||
|
@ -3278,30 +3178,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 ifa
|
|||
break;
|
||||
|
||||
case D3DTSS_TEXTURETRANSFORMFLAGS :
|
||||
{
|
||||
switch (Value & ~D3DTTFF_PROJECTED)
|
||||
{
|
||||
case D3DTTFF_DISABLE: /* Disable transform matrix for this texture by setting up the identity matrix */
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
checkGLcall("Load identity matrix for texture");
|
||||
glMatrixMode(GL_MODELVIEW); /* Always leave in model view */
|
||||
break;
|
||||
|
||||
default: /* Enable it */
|
||||
IDirect3DDevice8Impl_SetTransform(iface, D3DTS_TEXTURE0+Stage, &This->UpdateStateBlock->transforms[D3DTS_TEXTURE0+Stage]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* From web: <quote source="opengl12.pdf" section="Apendix C, Version 1.1/Other changes"
|
||||
2. Texture coordinates s, t, and r are divided by q during the rasterization
|
||||
of points, pixel rectangles, and bitmaps. This division was documented
|
||||
only for lines and polygons in the 1.0 version. </quote>
|
||||
I interpret this as we can implement projected transforms in slow vertex mode
|
||||
by moving the last coord to the 'q' coord and using one less dimension. The only
|
||||
way to do it in TexCoordPtr would be to massage the data stream to insert extra
|
||||
coords */
|
||||
}
|
||||
set_texture_matrix((float *)&This->StateBlock->transforms[D3DTS_TEXTURE0 + Stage].u.m[0][0], Value);
|
||||
break;
|
||||
|
||||
case D3DTSS_MIPMAPLODBIAS :
|
||||
|
|
|
@ -1083,6 +1083,12 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface,
|
|||
IDirect3DDevice8Impl_SetViewport((LPDIRECT3DDEVICE8) object, &vp);
|
||||
}
|
||||
|
||||
/* Initialize the current view state */
|
||||
object->modelview_valid = 1;
|
||||
object->proj_valid = 0;
|
||||
object->view_ident = 1;
|
||||
object->last_was_rhw = 0;
|
||||
|
||||
TRACE("(%p,%d) All defaults now set up, leaving CreateDevice\n", This, Adapter);
|
||||
return D3D_OK;
|
||||
}
|
||||
|
|
|
@ -172,67 +172,90 @@ BOOL primitiveInitState(LPDIRECT3DDEVICE8 iface, BOOL vtx_transformed, BOOL vtx_
|
|||
isLightingOn = glIsEnabled(GL_LIGHTING);
|
||||
glDisable(GL_LIGHTING);
|
||||
checkGLcall("glDisable(GL_LIGHTING);");
|
||||
TRACE("Enabled lighting as no normals supplied, old state = %d\n", isLightingOn);
|
||||
TRACE("Disabled lighting as no normals supplied, old state = %d\n", isLightingOn);
|
||||
}
|
||||
|
||||
if (vtx_transformed) {
|
||||
double X, Y, height, width, minZ, maxZ;
|
||||
|
||||
/* Transformed already into viewport coordinates, so we do not need transform
|
||||
matrices. Reset all matrices to identity and leave the default matrix in world
|
||||
mode. */
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
checkGLcall("glMatrixMode");
|
||||
glLoadIdentity();
|
||||
checkGLcall("glLoadIdentity");
|
||||
/* If the last draw was transformed as well, no need to reapply all the matrixes */
|
||||
if (!This->last_was_rhw) {
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
checkGLcall("glMatrixMode");
|
||||
glLoadIdentity();
|
||||
checkGLcall("glLoadIdentity");
|
||||
double X, Y, height, width, minZ, maxZ;
|
||||
This->last_was_rhw = TRUE;
|
||||
|
||||
/* Set up the viewport to be full viewport */
|
||||
X = This->StateBlock->viewport.X;
|
||||
Y = This->StateBlock->viewport.Y;
|
||||
height = This->StateBlock->viewport.Height;
|
||||
width = This->StateBlock->viewport.Width;
|
||||
minZ = This->StateBlock->viewport.MinZ;
|
||||
maxZ = This->StateBlock->viewport.MaxZ;
|
||||
TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
|
||||
glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
|
||||
checkGLcall("glOrtho");
|
||||
/* Transformed already into viewport coordinates, so we do not need transform
|
||||
matrices. Reset all matrices to identity and leave the default matrix in world
|
||||
mode. */
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
checkGLcall("glMatrixMode");
|
||||
glLoadIdentity();
|
||||
checkGLcall("glLoadIdentity");
|
||||
|
||||
/* Window Coord 0 is the middle of the first pixel, so translate by half
|
||||
a pixel (See comment above glTranslate below) */
|
||||
glTranslatef(0.5, 0.5, 0);
|
||||
checkGLcall("glTranslatef(0.5, 0.5, 0)");
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
checkGLcall("glMatrixMode");
|
||||
glLoadIdentity();
|
||||
checkGLcall("glLoadIdentity");
|
||||
|
||||
/* Set up the viewport to be full viewport */
|
||||
X = This->StateBlock->viewport.X;
|
||||
Y = This->StateBlock->viewport.Y;
|
||||
height = This->StateBlock->viewport.Height;
|
||||
width = This->StateBlock->viewport.Width;
|
||||
minZ = This->StateBlock->viewport.MinZ;
|
||||
maxZ = This->StateBlock->viewport.MaxZ;
|
||||
TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
|
||||
glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
|
||||
checkGLcall("glOrtho");
|
||||
|
||||
/* Window Coord 0 is the middle of the first pixel, so translate by half
|
||||
a pixel (See comment above glTranslate below) */
|
||||
glTranslatef(0.5, 0.5, 0);
|
||||
checkGLcall("glTranslatef(0.5, 0.5, 0)");
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* Untransformed, so relies on the view and projection matrices */
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
checkGLcall("glMatrixMode");
|
||||
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");
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
checkGLcall("glMatrixMode");
|
||||
if (This->last_was_rhw || !This->modelview_valid) {
|
||||
/* Only reapply when have to */
|
||||
This->modelview_valid = TRUE;
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
checkGLcall("glMatrixMode");
|
||||
|
||||
/* The rule is that the window coordinate 0 does not correspond to the
|
||||
beginning of the first pixel, but the center of the first pixel.
|
||||
As a consequence if you want to correctly draw one line exactly from
|
||||
the left to the right end of the viewport (with all matrices set to
|
||||
be identity), the x coords of both ends of the line would be not
|
||||
-1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
|
||||
instead. */
|
||||
glLoadIdentity();
|
||||
glTranslatef(1.0/This->StateBlock->viewport.Width, -1.0/This->StateBlock->viewport.Height, 0);
|
||||
checkGLcall("glTranslatef (1.0/width, -1.0/height, 0)");
|
||||
glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]);
|
||||
checkGLcall("glLoadMatrixf");
|
||||
/* In the general case, the view matrix is the identity matrix */
|
||||
if (This->view_ident) {
|
||||
glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
|
||||
checkGLcall("glLoadMatrixf");
|
||||
} else {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
if (This->last_was_rhw || !This->proj_valid) {
|
||||
/* Only reapply when have to */
|
||||
This->proj_valid = TRUE;
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
checkGLcall("glMatrixMode");
|
||||
|
||||
/* The rule is that the window coordinate 0 does not correspond to the
|
||||
beginning of the first pixel, but the center of the first pixel.
|
||||
As a consequence if you want to correctly draw one line exactly from
|
||||
the left to the right end of the viewport (with all matrices set to
|
||||
be identity), the x coords of both ends of the line would be not
|
||||
-1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
|
||||
instead. */
|
||||
glLoadIdentity();
|
||||
glTranslatef(1.0/This->StateBlock->viewport.Width, -1.0/This->StateBlock->viewport.Height, 0);
|
||||
checkGLcall("glTranslatef (1.0/width, -1.0/height, 0)");
|
||||
glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]);
|
||||
checkGLcall("glLoadMatrixf");
|
||||
}
|
||||
|
||||
This->last_was_rhw = FALSE;
|
||||
}
|
||||
return isLightingOn;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue