wined3d: Non power of two texture fixes.

This commit is contained in:
Stefan Dösinger 2007-11-13 22:08:13 +01:00 committed by Alexandre Julliard
parent 0334c1760f
commit 26f7eae9cf
5 changed files with 33 additions and 84 deletions

View file

@ -230,40 +230,8 @@ static UINT WINAPI IWineD3DCubeTextureImpl_GetTextureDimensions(IWineD3DCubeText
static void WINAPI IWineD3DCubeTextureImpl_ApplyStateChanges(IWineD3DCubeTexture *iface,
const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
float matrix[16];
TRACE("(%p) : relay to BaseTexture\n", iface);
IWineD3DBaseTextureImpl_ApplyStateChanges((IWineD3DBaseTexture *)iface, textureStates, samplerStates);
/* Apply non-power2 mappings and texture offsets so long as the texture coords aren't projected or generated */
if(This->pow2scalingFactor != 1.0f) {
if((textureStates[WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) == WINED3DTSS_TCI_PASSTHRU &&
(~textureStates[WINED3DTSS_TEXTURETRANSFORMFLAGS] & WINED3DTTFF_PROJECTED)) {
glMatrixMode(GL_TEXTURE);
memset(matrix, 0 , sizeof(matrix));
matrix[0] = This->pow2scalingFactor;
matrix[5] = This->pow2scalingFactor;
matrix[10] = This->pow2scalingFactor;
#if 0 /* Translation fixup is no longer required (here for reminder) */
matrix[12] = -0.25f / (float)This->edgeLength;
matrix[13] = -0.75f / (float)This->edgeLength;
matrix[14] = -0.25f / (float)This->edgeLength;
#endif
TRACE("(%p) Setup Matrix:\n", This);
TRACE(" %f %f %f %f\n", matrix[0], matrix[1], matrix[2], matrix[3]);
TRACE(" %f %f %f %f\n", matrix[4], matrix[5], matrix[6], matrix[7]);
TRACE(" %f %f %f %f\n", matrix[8], matrix[9], matrix[10], matrix[11]);
TRACE(" %f %f %f %f\n", matrix[12], matrix[13], matrix[14], matrix[15]);
TRACE("\n");
glMultMatrixf(matrix);
} else {
/* I don't expect nonpower 2 textures to be used with generated texture coordinates, but if they are present a fixme. */
FIXME("Non-power2 texture being used with generated texture coords\n");
}
}
}

View file

@ -880,9 +880,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, U
/** FIXME: add support for real non-power-two if it's provided by the video card **/
/* Precalculated scaling for 'faked' non power of two texture coords */
object->pow2scalingFactorX = (((float)Width) / ((float)pow2Width));
object->pow2scalingFactorY = (((float)Height) / ((float)pow2Height));
TRACE(" xf(%f) yf(%f)\n", object->pow2scalingFactorX, object->pow2scalingFactorY);
object->baseTexture.pow2Matrix[0] = (((float)Width) / ((float)pow2Width));
object->baseTexture.pow2Matrix[5] = (((float)Height) / ((float)pow2Height));
object->baseTexture.pow2Matrix[10] = 1.0;
object->baseTexture.pow2Matrix[15] = 1.0;
TRACE(" xf(%f) yf(%f)\n", object->baseTexture.pow2Matrix[0], object->baseTexture.pow2Matrix[5]);
/* Calculate levels for mip mapping */
if (Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
@ -976,6 +978,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa
object->height = Height;
object->depth = Depth;
/* Is NP2 support for volumes needed? */
object->baseTexture.pow2Matrix[ 0] = 1.0;
object->baseTexture.pow2Matrix[ 5] = 1.0;
object->baseTexture.pow2Matrix[10] = 1.0;
object->baseTexture.pow2Matrix[15] = 1.0;
/* Calculate levels for mip mapping */
if (Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
if(!GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
@ -1112,7 +1120,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface
object->edgeLength = EdgeLength;
/* TODO: support for native non-power 2 */
/* Precalculated scaling for 'faked' non power of two texture coords */
object->pow2scalingFactor = ((float)EdgeLength) / ((float)pow2EdgeLength);
object->baseTexture.pow2Matrix[ 0] = ((float)EdgeLength) / ((float)pow2EdgeLength);
object->baseTexture.pow2Matrix[ 5] = ((float)EdgeLength) / ((float)pow2EdgeLength);
object->baseTexture.pow2Matrix[10] = ((float)EdgeLength) / ((float)pow2EdgeLength);
object->baseTexture.pow2Matrix[15] = 1.0;
/* Calculate levels for mip mapping */
if (Usage & WINED3DUSAGE_AUTOGENMIPMAP) {

View file

@ -1904,6 +1904,7 @@ static void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
DWORD texUnit = state - STATE_TRANSFORM(WINED3DTS_TEXTURE0);
DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[texUnit];
BOOL generated;
/* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
if(use_vs(stateblock->wineD3DDevice) ||
@ -1925,15 +1926,24 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W
WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
return;
}
generated = (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU;
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,
generated,
context->last_was_rhw,
stateblock->wineD3DDevice->strided_streams.u.s.texCoords[texUnit].dwStride ?
stateblock->wineD3DDevice->strided_streams.u.s.texCoords[texUnit].dwType:
WINED3DDECLTYPE_UNUSED);
/* The sampler applying function calls us if this changes */
if(context->lastWasPow2Texture[texUnit] && stateblock->textures[texUnit]) {
if(generated) {
FIXME("Non-power2 texture being used with generated texture coords\n");
}
TRACE("Non power two matrix multiply fixup\n");
glMultMatrixf(((IWineD3DTextureImpl *) stateblock->textures[texUnit])->baseTexture.pow2Matrix);
}
}
static void unloadTexCoords(IWineD3DStateBlockImpl *stateblock) {
@ -2289,19 +2299,19 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
*/
if(!GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) && sampler < MAX_TEXTURES) {
if(stateblock->textureDimensions[sampler] == GL_TEXTURE_2D) {
if(((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorX != 1.0 ||
((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorY != 1.0 ) {
if(((IWineD3DTextureImpl *) stateblock->textures[sampler])->baseTexture.pow2Matrix[0] != 1.0 ||
((IWineD3DTextureImpl *) stateblock->textures[sampler])->baseTexture.pow2Matrix[5] != 1.0 ) {
texIsPow2 = TRUE;
}
} else if(stateblock->textureDimensions[sampler] == GL_TEXTURE_CUBE_MAP_ARB) {
if(((IWineD3DCubeTextureImpl *) stateblock->textures[sampler])->pow2scalingFactor != 1.0) {
if(((IWineD3DCubeTextureImpl *) stateblock->textures[sampler])->baseTexture.pow2Matrix[0] != 1.0) {
texIsPow2 = TRUE;
}
}
if(texIsPow2 || context->lastWasPow2Texture[sampler]) {
transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stateblock->wineD3DDevice->texUnitMap[sampler]), stateblock, context);
context->lastWasPow2Texture[sampler] = texIsPow2;
transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stateblock->wineD3DDevice->texUnitMap[sampler]), stateblock, context);
}
}

View file

@ -213,39 +213,8 @@ static UINT WINAPI IWineD3DTextureImpl_GetTextureDimensions(IWineD3DTexture *ifa
static void WINAPI IWineD3DTextureImpl_ApplyStateChanges(IWineD3DTexture *iface,
const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
float matrix[16];
TRACE("(%p) : relay to BaseTexture\n", iface);
IWineD3DBaseTextureImpl_ApplyStateChanges((IWineD3DBaseTexture *)iface, textureStates, samplerStates);
/** non-power2 fixups using texture matrix **/
if(This->pow2scalingFactorX != 1.0f || This->pow2scalingFactorY != 1.0f) {
/* Apply non-power2 mappings and texture offsets so long as the texture coords aren't projected or generated */
if(((textureStates[WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) == WINED3DTSS_TCI_PASSTHRU) &&
(~textureStates[WINED3DTSS_TEXTURETRANSFORMFLAGS] & WINED3DTTFF_PROJECTED)) {
glMatrixMode(GL_TEXTURE);
memset(matrix, 0 , sizeof(matrix));
matrix[0] = This->pow2scalingFactorX;
matrix[5] = This->pow2scalingFactorY;
#if 0 /* this isn't needed any more, I changed the translation in drawprim.c to 0.9/width instead of 1/width and everything lines up ok. left here as a reminder */
matrix[12] = -0.25f / (float)This->width;
matrix[13] = -0.75f / (float)This->height;
#endif
matrix[10] = 1;
matrix[15] = 1;
TRACE("(%p) Setup Matrix:\n", This);
TRACE(" %f %f %f %f\n", matrix[0], matrix[1], matrix[2], matrix[3]);
TRACE(" %f %f %f %f\n", matrix[4], matrix[5], matrix[6], matrix[7]);
TRACE(" %f %f %f %f\n", matrix[8], matrix[9], matrix[10], matrix[11]);
TRACE(" %f %f %f %f\n", matrix[12], matrix[13], matrix[14], matrix[15]);
TRACE("\n");
glMultMatrixf(matrix);
} else {
/* I don't expect nonpower 2 textures to be used with generated texture coordinates, but if they are present a fixme. */
FIXME("Non-power2 texture being used with generated texture coords\n");
}
}
}
/* *******************************************

View file

@ -924,6 +924,7 @@ typedef struct IWineD3DBaseTextureClass
BOOL is_srgb;
UINT srgb_mode_change_count;
WINED3DFORMAT shader_conversion_group;
float pow2Matrix[16];
} IWineD3DBaseTextureClass;
typedef struct IWineD3DBaseTextureImpl
@ -950,8 +951,6 @@ typedef struct IWineD3DTextureImpl
UINT width;
UINT height;
float pow2scalingFactorX;
float pow2scalingFactorY;
} IWineD3DTextureImpl;
@ -971,8 +970,6 @@ typedef struct IWineD3DCubeTextureImpl
IWineD3DSurface *surfaces[6][MAX_LEVELS];
UINT edgeLength;
float pow2scalingFactor;
} IWineD3DCubeTextureImpl;
extern const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl;
@ -1097,12 +1094,6 @@ struct IWineD3DSurfaceImpl
/* PBO */
GLuint pbo;
#if 0
/* precalculated x and y scalings for texture coords */
float pow2scalingFactorX; /* = (Width / pow2Width ) */
float pow2scalingFactorY; /* = (Height / pow2Height) */
#endif
RECT lockedRect;
RECT dirtyRect;
int lockCount;