wined3d: Some texture transform fixes.

oldstable
Stefan Dösinger 2007-08-27 14:33:46 +02:00 committed by Alexandre Julliard
parent a8e21d0692
commit fe0f0eb48a
4 changed files with 66 additions and 15 deletions

View File

@ -414,6 +414,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
ptrToCoords = (float *)(texCoords[coordIdx] + (SkipnStrides * sd->u.s.texCoords[coordIdx].dwStride));
if (texCoords[coordIdx] == NULL) {
TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo);
glTexCoord4f(0, 0, 0, 1);
continue;
} else {
int texture_idx = This->texUnitMap[textureNo];

View File

@ -1859,6 +1859,13 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W
DWORD texUnit = state - STATE_TRANSFORM(WINED3DTS_TEXTURE0);
DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[texUnit];
/* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
if(stateblock->vertexShader ||
isStateDirty(context, STATE_VDECL)) {
TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
return;
}
if (mapped_stage < 0) return;
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
@ -1876,7 +1883,10 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W
set_texture_matrix((float *)&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS],
(stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU,
context->last_was_rhw);
context->last_was_rhw,
stateblock->wineD3DDevice->strided_streams.u.s.texCoords[texUnit].dwStride ?
stateblock->wineD3DDevice->strided_streams.u.s.texCoords[texUnit].dwType:
WINED3DDECLTYPE_UNUSED);
}
@ -3199,7 +3209,7 @@ static inline void handleStreams(IWineD3DStateBlockImpl *stateblock, BOOL useVer
}
static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
BOOL useVertexShaderFunction = FALSE, updateFog = FALSE, updateTexMatrices = FALSE;
BOOL useVertexShaderFunction = FALSE, updateFog = FALSE;
BOOL usePixelShaderFunction = stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader
&& ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function;
BOOL transformed;
@ -3228,7 +3238,6 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
updateFog = TRUE;
updateTexMatrices = TRUE;
}
/* Reapply lighting if it is not scheduled for reapplication already */
@ -3333,7 +3342,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
if(updateFog) {
state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock, context);
}
if(updateTexMatrices) {
if(!useVertexShaderFunction) {
int i;
for(i = 0; i < MAX_TEXTURES; i++) {
if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + i))) {

View File

@ -2418,14 +2418,14 @@ void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP
#endif
/* Setup this textures matrix according to the texture flags*/
void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed)
void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype)
{
float mat[16];
glMatrixMode(GL_TEXTURE);
checkGLcall("glMatrixMode(GL_TEXTURE)");
if (flags == WINED3DTTFF_DISABLE || transformed) {
if (flags == WINED3DTTFF_DISABLE || flags == WINED3DTTFF_COUNT1 || transformed) {
glLoadIdentity();
checkGLcall("glLoadIdentity()");
return;
@ -2438,12 +2438,6 @@ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, B
memcpy(mat, smat, 16 * sizeof(float));
switch (flags & ~WINED3DTTFF_PROJECTED) {
case WINED3DTTFF_COUNT1: mat[1] = mat[5] = mat[13] = 0;
case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
default: mat[3] = mat[7] = mat[11] = 0, mat[15] = 1;
}
if (flags & WINED3DTTFF_PROJECTED) {
switch (flags & ~WINED3DTTFF_PROJECTED) {
case WINED3DTTFF_COUNT2:
@ -2456,8 +2450,55 @@ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, B
break;
}
} else if(!calculatedCoords) { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
mat[12] = mat[8];
mat[13] = mat[9];
switch(coordtype) {
case WINED3DDECLTYPE_FLOAT1:
/* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
* swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
* the input value to the transformation will be 0, so the matrix value is irrelevant
*/
mat[12] = mat[4];
mat[13] = mat[5];
mat[14] = mat[6];
mat[15] = mat[7];
break;
case WINED3DDECLTYPE_FLOAT2:
/* See above, just 3rd and 4th coord
*/
mat[12] = mat[8];
mat[13] = mat[9];
mat[14] = mat[10];
mat[15] = mat[11];
break;
case WINED3DDECLTYPE_FLOAT3: /* Opengl defaults match dx defaults */
case WINED3DDECLTYPE_FLOAT4: /* No defaults apply, all app defined */
/* This is to prevent swaping the matrix lines and put the default 4th coord = 1.0
* into a bad place. The division elimination below will apply to make sure the
* 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
*/
case WINED3DDECLTYPE_UNUSED: /* No texture coords, 0/0/0/1 defaults are passed */
break;
default:
FIXME("Unexpected fixed function texture coord input\n");
}
switch (flags & ~WINED3DTTFF_PROJECTED) {
/* case WINED3DTTFF_COUNT1: Won't ever get here */
case WINED3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
/* OpenGL divides the first 3 vertex coord by the 4th by default,
* which is essentially the same as D3DTTFF_PROJECTED. Make sure that
* the 4th coord evaluates to 1.0 to eliminate that.
*
* If the fixed function pipeline is used, the 4th value remains unused,
* so there is no danger in doing this. With vertex shaders we have a
* problem. Should an app hit that problem, the code here would have to
* check for pixel shaders, and the shader has to undo the default gl divide.
*
* A more serious problem occurs if the app passes 4 coordinates in, and the
* 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
* or a replacement shader
*/
default: mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
}
}
glLoadMatrixf(mat);

View File

@ -1532,7 +1532,7 @@ GLenum StencilOp(DWORD op);
GLenum CompareFunc(DWORD func);
void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx);
void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed);
void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype);
void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height);
GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchain);