advpack: Fix the documentation for RegisterOCX.
[wine] / dlls / wined3d / basetexture.c
1 /*
2  * IWineD3DBaseTexture Implementation
3  *
4  * Copyright 2002-2004 Jason Edmeades
5  * Copyright 2002-2004 Raphael Junqueira
6  * Copyright 2005 Oliver Stieber
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include "config.h"
24 #include "wined3d_private.h"
25
26 WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
27 #define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->resource.wineD3DDevice)->wineD3D))->gl_info
28
29 static const Wined3dTextureStateMap textureObjectSamplerStates[]  = {
30     {WINED3DSAMP_ADDRESSU,      WINED3DSAMP_ADDRESSU},
31     {WINED3DSAMP_ADDRESSV,      WINED3DSAMP_ADDRESSV},
32     {WINED3DSAMP_ADDRESSW,      WINED3DSAMP_ADDRESSW},
33 /* NOTE: Sometimes it's a good idea to disable the setting of border colour, e.g. Axis and Allies */
34     {WINED3DSAMP_BORDERCOLOR,   WINED3DFUNC_NOTSUPPORTED/* WINED3DSAMP_BORDERCOLOR */},
35     {WINED3DSAMP_MAGFILTER,     WINED3DSAMP_MAGFILTER},
36     {WINED3DSAMP_MINFILTER,     WINED3DSAMP_MINFILTER},
37     {WINED3DSAMP_MIPFILTER,     WINED3DSAMP_MIPFILTER},
38 /* applies to the texture unit
39     WINED3DSAMP_MIPMAPLODBIAS, WINED3DSAMP_MIPMAPLODBIAS,
40 */
41     {WINED3DSAMP_MAXMIPLEVEL,   WINED3DSAMP_MAXMIPLEVEL},
42 #if 0
43     {WINED3DSAMP_MAXANISOTROPY, GL_SUPPORTED(EXT_TEXTURE_FILTER_ANISOTROPIC) ? WINED3DSAMP_MAXANISOTROPY : WINED3DFUNC_NOTSUPPORTED},
44 #else
45     {WINED3DSAMP_MAXANISOTROPY, WINED3DSAMP_MAXANISOTROPY},
46 #endif
47     {WINED3DSAMP_SRGBTEXTURE,   WINED3DFUNC_UNIMPLEMENTED},
48     {WINED3DSAMP_ELEMENTINDEX,  WINED3DFUNC_UNIMPLEMENTED},
49     {WINED3DSAMP_DMAPOFFSET,    WINED3DFUNC_UNIMPLEMENTED},
50     {-1, 0}
51 };
52
53 static const Wined3dTextureStateMap textureObjectTextureStates[] = {
54     {WINED3DTSS_ADDRESSW , WINED3DTSS_ADDRESSW},
55     {-1, 0}
56 };
57
58 /* *******************************************
59    IWineD3DBaseTexture IUnknown parts follow
60    ******************************************* */
61 HRESULT WINAPI IWineD3DBaseTextureImpl_QueryInterface(IWineD3DBaseTexture *iface, REFIID riid, LPVOID *ppobj)
62 {
63     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
64     TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
65     if (IsEqualGUID(riid, &IID_IUnknown)
66         || IsEqualGUID(riid, &IID_IWineD3DBase)
67         || IsEqualGUID(riid, &IID_IWineD3DResource)
68         || IsEqualGUID(riid, &IID_IWineD3DBaseTexture)) {
69         IUnknown_AddRef(iface);
70         *ppobj = This;
71         return WINED3D_OK;
72     }
73     return E_NOINTERFACE;
74 }
75
76 ULONG WINAPI IWineD3DBaseTextureImpl_AddRef(IWineD3DBaseTexture *iface) {
77     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
78     ULONG ref = InterlockedIncrement(&This->resource.ref);
79
80     TRACE("(%p) : AddRef increasing from %ld\n", This,ref - 1);
81     return ref;
82 }
83
84 ULONG WINAPI IWineD3DBaseTextureImpl_Release(IWineD3DBaseTexture *iface) {
85     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
86     ULONG ref = InterlockedDecrement(&This->resource.ref);
87     TRACE("(%p) : Releasing from %ld\n", This, ref + 1);
88     if (ref == 0) {
89         IWineD3DBaseTextureImpl_CleanUp(iface);
90         HeapFree(GetProcessHeap(), 0, This);
91     }
92     return ref;
93 }
94
95 /* class static */
96 void IWineD3DBaseTextureImpl_CleanUp(IWineD3DBaseTexture *iface) {
97     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
98     TRACE("(%p) : textureName(%d)\n", This, This->baseTexture.textureName);
99     if (This->baseTexture.textureName != 0) {
100         ENTER_GL();
101         TRACE("(%p) : Deleting texture %d\n", This, This->baseTexture.textureName);
102         glDeleteTextures(1, &This->baseTexture.textureName);
103         LEAVE_GL();
104     }
105     IWineD3DResourceImpl_CleanUp((IWineD3DResource *)iface);
106 }
107
108 /* ****************************************************
109    IWineD3DBaseTexture IWineD3DResource parts follow
110    **************************************************** */
111 HRESULT WINAPI IWineD3DBaseTextureImpl_GetDevice(IWineD3DBaseTexture *iface, IWineD3DDevice** ppDevice) {
112     return IWineD3DResourceImpl_GetDevice((IWineD3DResource *)iface, ppDevice);
113 }
114
115 HRESULT WINAPI IWineD3DBaseTextureImpl_SetPrivateData(IWineD3DBaseTexture *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
116     return IWineD3DResourceImpl_SetPrivateData((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
117 }
118
119 HRESULT WINAPI IWineD3DBaseTextureImpl_GetPrivateData(IWineD3DBaseTexture *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
120     return IWineD3DResourceImpl_GetPrivateData((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
121 }
122
123 HRESULT WINAPI IWineD3DBaseTextureImpl_FreePrivateData(IWineD3DBaseTexture *iface, REFGUID refguid) {
124     return IWineD3DResourceImpl_FreePrivateData((IWineD3DResource *)iface, refguid);
125 }
126
127 DWORD    WINAPI        IWineD3DBaseTextureImpl_SetPriority(IWineD3DBaseTexture *iface, DWORD PriorityNew) {
128     return IWineD3DResourceImpl_SetPriority((IWineD3DResource *)iface, PriorityNew);
129 }
130
131 DWORD    WINAPI        IWineD3DBaseTextureImpl_GetPriority(IWineD3DBaseTexture *iface) {
132     return IWineD3DResourceImpl_GetPriority((IWineD3DResource *)iface);
133 }
134
135 void     WINAPI        IWineD3DBaseTextureImpl_PreLoad(IWineD3DBaseTexture *iface) {
136     return IWineD3DResourceImpl_PreLoad((IWineD3DResource *)iface);
137 }
138
139 WINED3DRESOURCETYPE WINAPI IWineD3DBaseTextureImpl_GetType(IWineD3DBaseTexture *iface) {
140     return IWineD3DResourceImpl_GetType((IWineD3DResource *)iface);
141 }
142
143 HRESULT WINAPI IWineD3DBaseTextureImpl_GetParent(IWineD3DBaseTexture *iface, IUnknown **pParent) {
144     return IWineD3DResourceImpl_GetParent((IWineD3DResource *)iface, pParent);
145 }
146
147 /* ******************************************************
148    IWineD3DBaseTexture IWineD3DBaseTexture parts follow
149    ****************************************************** */
150
151 /* There is no OpenGL equivilent of setLOD, getLOD, all they do it priortise testure loading
152  * so just pretend that they work unless something really needs a failure. */
153 DWORD WINAPI IWineD3DBaseTextureImpl_SetLOD(IWineD3DBaseTexture *iface, DWORD LODNew) {
154     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
155
156     if (This->resource.pool != WINED3DPOOL_MANAGED) {
157         return  WINED3DERR_INVALIDCALL;
158     }
159
160     if(LODNew >= This->baseTexture.levels)
161         LODNew = This->baseTexture.levels - 1;
162      This->baseTexture.LOD = LODNew;
163
164     TRACE("(%p) : set bogus LOD to %d\n", This, This->baseTexture.LOD);
165
166     return This->baseTexture.LOD;
167 }
168
169 DWORD WINAPI IWineD3DBaseTextureImpl_GetLOD(IWineD3DBaseTexture *iface) {
170     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
171
172     if (This->resource.pool != WINED3DPOOL_MANAGED) {
173         return  WINED3DERR_INVALIDCALL;
174     }
175
176     TRACE("(%p) : returning %d\n", This, This->baseTexture.LOD);
177
178     return This->baseTexture.LOD;
179 }
180
181 DWORD WINAPI IWineD3DBaseTextureImpl_GetLevelCount(IWineD3DBaseTexture *iface) {
182     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
183     TRACE("(%p) : returning %d\n", This, This->baseTexture.levels);
184     return This->baseTexture.levels;
185 }
186
187 HRESULT WINAPI IWineD3DBaseTextureImpl_SetAutoGenFilterType(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) {
188   IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
189
190   if (!(This->baseTexture.usage & WINED3DUSAGE_AUTOGENMIPMAP)) {
191       TRACE("(%p) : returning invalid call\n", This);
192       return WINED3DERR_INVALIDCALL;
193   }
194   This->baseTexture.filterType = FilterType;
195   TRACE("(%p) :\n", This);
196   return WINED3D_OK;
197 }
198
199 WINED3DTEXTUREFILTERTYPE WINAPI IWineD3DBaseTextureImpl_GetAutoGenFilterType(IWineD3DBaseTexture *iface) {
200   IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
201   FIXME("(%p) : stub\n", This);
202   if (!(This->baseTexture.usage & WINED3DUSAGE_AUTOGENMIPMAP)) {
203      return WINED3DTEXF_NONE;
204   }
205   return This->baseTexture.filterType;
206 }
207
208 void WINAPI IWineD3DBaseTextureImpl_GenerateMipSubLevels(IWineD3DBaseTexture *iface) {
209   IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
210   /* TODO: implement filters using GL_SGI_generate_mipmaps http://oss.sgi.com/projects/ogl-sample/registry/SGIS/generate_mipmap.txt */
211   FIXME("(%p) : stub\n", This);
212   return ;
213 }
214
215 /* Internal function, No d3d mapping */
216 BOOL WINAPI IWineD3DBaseTextureImpl_SetDirty(IWineD3DBaseTexture *iface, BOOL dirty) {
217     BOOL old;
218     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
219     old = This->baseTexture.dirty;
220     This->baseTexture.dirty = dirty;
221     return old;
222 }
223
224 BOOL WINAPI IWineD3DBaseTextureImpl_GetDirty(IWineD3DBaseTexture *iface) {
225     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
226     return This->baseTexture.dirty;
227 }
228
229 HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface) {
230     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
231     HRESULT hr = WINED3D_OK;
232     UINT textureDimensions;
233     BOOL isNewTexture = FALSE;
234     TRACE("(%p) : About to bind texture\n", This);
235
236     textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
237     ENTER_GL();
238 #if 0 /* TODO: context manager support */
239      IWineD3DContextManager_PushState(This->contextManager, textureDimensions, ENABLED, NOW /* make sure the state is applied now */);
240 #else
241     glEnable(textureDimensions);
242 #endif
243
244     /* Generate a texture name if we don't already have one */
245     if (This->baseTexture.textureName == 0) {
246         glGenTextures(1, &This->baseTexture.textureName);
247         checkGLcall("glGenTextures");
248         TRACE("Generated texture %d\n", This->baseTexture.textureName);
249         if (This->resource.pool == WINED3DPOOL_DEFAULT) {
250             /* Tell opengl to try and keep this texture in video ram (well mostly) */
251             GLclampf tmp;
252             tmp = 0.9f;
253             glPrioritizeTextures(1, &This->baseTexture.textureName, &tmp);
254
255         }
256         /* Initialise the state of the texture object
257         to the openGL defaults, not the directx defaults */
258         This->baseTexture.states[WINED3DTEXSTA_ADDRESSU]      = D3DTADDRESS_WRAP;
259         This->baseTexture.states[WINED3DTEXSTA_ADDRESSV]      = D3DTADDRESS_WRAP;
260         This->baseTexture.states[WINED3DTEXSTA_ADDRESSW]      = D3DTADDRESS_WRAP;
261         This->baseTexture.states[WINED3DTEXSTA_BORDERCOLOR]   = 0;
262         This->baseTexture.states[WINED3DTEXSTA_MAGFILTER]     = WINED3DTEXF_LINEAR;
263         This->baseTexture.states[WINED3DTEXSTA_MINFILTER]     = WINED3DTEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */
264         This->baseTexture.states[WINED3DTEXSTA_MIPFILTER]     = WINED3DTEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */
265         This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL]   = 0;
266         This->baseTexture.states[WINED3DTEXSTA_MAXANISOTROPY] = 0;
267         This->baseTexture.states[WINED3DTEXSTA_SRGBTEXTURE]   = 0;
268         This->baseTexture.states[WINED3DTEXSTA_ELEMENTINDEX]  = 0;
269         This->baseTexture.states[WINED3DTEXSTA_DMAPOFFSET]    = 0;
270         This->baseTexture.states[WINED3DTEXSTA_TSSADDRESSW]   = D3DTADDRESS_WRAP;
271         IWineD3DBaseTexture_SetDirty(iface, TRUE);
272         isNewTexture = TRUE;
273     }
274
275     /* Bind the texture */
276     if (This->baseTexture.textureName != 0) {
277         glBindTexture(textureDimensions, This->baseTexture.textureName);
278         checkGLcall("glBindTexture");
279         if (isNewTexture) {
280             /* For a new texture we have to set the textures levels after binding the texture,
281             * in theory this is all we should ever have to dom, but because ATI's drivers are broken we
282             * also need to set the texture dimensins before the texture is is set */
283             TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1);
284             glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1);
285             checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels)");
286         }
287                 
288     } else { /* this only happened if we've run out of openGL textures */
289         WARN("This texture doesn't have an openGL texture assigned to it\n");
290         hr =  WINED3DERR_INVALIDCALL;
291     }
292
293     LEAVE_GL();
294     return hr;
295 }
296
297 HRESULT WINAPI IWineD3DBaseTextureImpl_UnBindTexture(IWineD3DBaseTexture *iface) {
298     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
299     UINT textureDimensions;
300
301     TRACE("(%p) : About to bind texture\n", This);
302     textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
303
304     ENTER_GL();
305
306     glBindTexture(textureDimensions, 0);
307 #if 0 /* TODO: context manager support */
308      IWineD3DContextManager_PopState(This->contextManager, textureDimensions, ENABLED, NOW /* make sure the state is applied now */);
309 #else
310     glDisable(textureDimensions);
311 #endif
312
313     LEAVE_GL();
314     return WINED3D_OK;
315 }
316
317 UINT WINAPI IWineD3DBaseTextureImpl_GetTextureDimensions(IWineD3DBaseTexture *iface){
318     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
319     FIXME("(%p) : This shouldn't be called\n", This);
320     return WINED3D_OK;
321 }
322
323 static inline GLenum warpLookupType(WINED3DSAMPLERSTATETYPE Type) {
324     switch(Type) {
325     case WINED3DSAMP_ADDRESSU:
326         return GL_TEXTURE_WRAP_S;
327     case WINED3DSAMP_ADDRESSV:
328         return GL_TEXTURE_WRAP_T;
329     case WINED3DSAMP_ADDRESSW:
330         return GL_TEXTURE_WRAP_R;
331     default:
332         FIXME("Unexpected warp type %d\n", Type);
333         return 0;
334     }
335 }
336
337 void WINAPI IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface,
338                                     const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
339                                     const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
340     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
341     int i;
342     DWORD *state = This->baseTexture.states;
343     GLint textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
344     IWineD3DBaseTexture_PreLoad(iface);
345     /* run through a couple of loops and apply and states that are different */
346     /* this will reduce the number of texture state changes to an absolute minimum
347     for multi-parameter states we  pickup the first one that changes, work out the correct values for the other states
348     and set all the states that we've just applied to their new values */
349
350     for (i = 0 ;textureObjectSamplerStates[i].state != -1; i++) {
351         if (*state != samplerStates[textureObjectSamplerStates[i].state]) {
352             /* apply the state */
353             TRACE("(%p) : Changing state %u from %ld to %ld\n", This, i, *state , samplerStates[textureObjectSamplerStates[i].state]);
354             switch (textureObjectSamplerStates[i].function) {
355             case WINED3DSAMP_ADDRESSU:
356             case WINED3DSAMP_ADDRESSV: /* fall through */
357             case WINED3DSAMP_ADDRESSW: /* fall through */
358                 *state = samplerStates[textureObjectSamplerStates[i].state];
359                 if (*state < minLookup[WINELOOKUP_WARPPARAM] || *state > maxLookup[WINELOOKUP_WARPPARAM]) {
360                     FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", *state, textureObjectSamplerStates[i].function);
361                 } else {
362                     GLint wrapParm = stateLookup[WINELOOKUP_WARPPARAM][*state - minLookup[WINELOOKUP_WARPPARAM]];
363                     TRACE("Setting WRAP_R to %d for %x\n", wrapParm, textureDimensions);
364                     glTexParameteri(textureDimensions, warpLookupType(textureObjectSamplerStates[i].function), wrapParm);
365                     checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
366                 }
367             break;
368             case WINED3DSAMP_BORDERCOLOR:
369             {
370                 float col[4];
371                 *state = samplerStates[textureObjectSamplerStates[i].state];
372                 D3DCOLORTOGLFLOAT4(*state, col);
373                 TRACE("Setting border color for %u to %lx\n", textureDimensions, *state);
374                 glTexParameterfv(textureDimensions, GL_TEXTURE_BORDER_COLOR, &col[0]);
375                 checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
376             }
377             break;
378             case WINED3DSAMP_MAGFILTER:
379                 {
380                     GLint glValue;
381                     *state = samplerStates[textureObjectSamplerStates[i].state];
382                     if (*state < minLookup[WINELOOKUP_MAGFILTER] || *state > maxLookup[WINELOOKUP_MAGFILTER]) {
383                         FIXME("Unrecognized or unsupported MAGFILTER* value %ld, state %d\n", *state, textureObjectSamplerStates[i].function);
384                     }
385                     glValue = stateLookup[WINELOOKUP_MAGFILTER][*state - minLookup[WINELOOKUP_MAGFILTER]];
386                     TRACE("ValueMAG=%ld setting MAGFILTER to %x\n", *state, glValue);
387                     glTexParameteri(textureDimensions, GL_TEXTURE_MAG_FILTER, glValue);
388                 /* We need to reset the Aniotropic filtering state when we change the mag filter to WINED3DTEXF_ANISOTROPIC (this seems a bit weird, check the documentataion to see how it should be switched off. */
389                     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && WINED3DTEXF_ANISOTROPIC == *state) {
390                         glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);
391                     }
392                 }
393             break;
394
395             case WINED3DSAMP_MINFILTER:
396                 This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] = samplerStates[WINED3DSAMP_MIPFILTER];
397             case WINED3DSAMP_MIPFILTER: /* fall through */
398                 {
399                     GLint glValue;
400                     *state = samplerStates[textureObjectSamplerStates[i].state];
401                     if (This->baseTexture.states[WINED3DTEXSTA_MINFILTER] < WINED3DTEXF_NONE ||
402                         This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] < WINED3DTEXF_NONE ||
403                         This->baseTexture.states[WINED3DTEXSTA_MINFILTER] > WINED3DTEXF_ANISOTROPIC ||
404                         This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] > WINED3DTEXF_LINEAR)
405                     {
406
407                         FIXME("Unrecognized or unsupported D3DSAMP_MINFILTER value %ld, state %d D3DSAMP_MIPFILTER value %ld, state %d\n",
408                                 This->baseTexture.states[WINED3DTEXSTA_MINFILTER],
409                                 textureObjectSamplerStates[WINED3DTEXSTA_MINFILTER].function,
410                                 This->baseTexture.states[WINED3DTEXSTA_MIPFILTER],
411                                 textureObjectSamplerStates[WINED3DTEXSTA_MIPFILTER].function);
412                     }
413                     glValue = minMipLookup[min(max(This->baseTexture.states[WINED3DTEXSTA_MINFILTER],WINED3DTEXF_NONE), WINED3DTEXF_ANISOTROPIC)]
414                                                 [min(max(This->baseTexture.states[WINED3DTEXSTA_MIPFILTER],WINED3DTEXF_NONE), WINED3DTEXF_LINEAR)];
415
416                     TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", 
417                             This->baseTexture.states[WINED3DTEXSTA_MINFILTER], 
418                             This->baseTexture.states[WINED3DTEXSTA_MIPFILTER], glValue);
419                     glTexParameteri(textureDimensions, GL_TEXTURE_MIN_FILTER, glValue);
420                     checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
421                 }
422             break;
423             case WINED3DSAMP_MAXMIPLEVEL:
424                 *state = samplerStates[textureObjectSamplerStates[i].state];
425                 /**
426                 * Not really the same, but the more apprioprate than nothing
427                 */
428                 glTexParameteri(textureDimensions, GL_TEXTURE_BASE_LEVEL, *state);
429             break;
430             case WINED3DSAMP_MAXANISOTROPY:
431                 *state = samplerStates[textureObjectSamplerStates[i].state];
432                 glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT,  *state);
433                 checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ...");
434             break;
435             case WINED3DFUNC_UNIMPLEMENTED: /* unimplemented */
436                 TRACE("(%p) : stub\n", This);
437                 *state = samplerStates[textureObjectSamplerStates[i].state];
438             break;
439             case WINED3DFUNC_NOTSUPPORTED: /* nop */
440                 TRACE("(%p) : %s function is not supported by this opengl implementation\n", This, "unknown" /* TODO: replace with debug_blah... */);
441                 *state = samplerStates[textureObjectSamplerStates[i].state];
442             break;
443             }
444         }
445         state++;
446     }
447
448     for(i = 0 ;textureObjectTextureStates[i].state != - 1; i++) {
449         if(*state != textureStates[textureObjectTextureStates[i].state] ) {
450             /* apply the state */
451             *state = textureStates[textureObjectTextureStates[i].state];
452             switch (textureObjectTextureStates[i].function) {
453             case WINED3DTSS_ADDRESSW:
454             /* I'm not sure what to do if this is set as well as ADDRESSW on the sampler, how do they interact together? */
455             break;
456             case WINED3DFUNC_UNIMPLEMENTED: /* unimplemented */
457             TRACE("(%p) : stub\n", This);
458             break;
459             case WINED3DFUNC_NOTSUPPORTED: /* nop */
460             TRACE("(%p) : function no supported by this opengl implementation\n", This);
461             break;
462             }
463         }
464         state++;
465     }
466 }
467
468
469 static const IWineD3DBaseTextureVtbl IWineD3DBaseTexture_Vtbl =
470 {
471     /* IUnknown */
472     IWineD3DBaseTextureImpl_QueryInterface,
473     IWineD3DBaseTextureImpl_AddRef,
474     IWineD3DBaseTextureImpl_Release,
475     /* IWineD3DResource */
476     IWineD3DBaseTextureImpl_GetParent,
477     IWineD3DBaseTextureImpl_GetDevice,
478     IWineD3DBaseTextureImpl_SetPrivateData,
479     IWineD3DBaseTextureImpl_GetPrivateData,
480     IWineD3DBaseTextureImpl_FreePrivateData,
481     IWineD3DBaseTextureImpl_SetPriority,
482     IWineD3DBaseTextureImpl_GetPriority,
483     IWineD3DBaseTextureImpl_PreLoad,
484     IWineD3DBaseTextureImpl_GetType,
485     /*IWineD3DBaseTexture*/
486     IWineD3DBaseTextureImpl_SetLOD,
487     IWineD3DBaseTextureImpl_GetLOD,
488     IWineD3DBaseTextureImpl_GetLevelCount,
489     IWineD3DBaseTextureImpl_SetAutoGenFilterType,
490     IWineD3DBaseTextureImpl_GetAutoGenFilterType,
491     IWineD3DBaseTextureImpl_GenerateMipSubLevels,
492     IWineD3DBaseTextureImpl_SetDirty,
493     IWineD3DBaseTextureImpl_GetDirty,
494     /* internal */
495     IWineD3DBaseTextureImpl_BindTexture,
496     IWineD3DBaseTextureImpl_UnBindTexture,
497     IWineD3DBaseTextureImpl_GetTextureDimensions,
498     IWineD3DBaseTextureImpl_ApplyStateChanges
499
500 };