wined3d: Some texture transform fixes.
This commit is contained in:
parent
a8e21d0692
commit
fe0f0eb48a
|
@ -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];
|
||||
|
|
|
@ -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))) {
|
||||
|
|
|
@ -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 */
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue