msi: Change an ERR to a WARN.
[wine.git] / dlls / wined3d / basetexture.c
blob58fb92df15bb9655eab432d391e679dab901e683
1 /*
2 * IWineD3DBaseTexture Implementation
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2002-2004 Raphael Junqueira
6 * Copyright 2005 Oliver Stieber
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "config.h"
24 #include "wined3d_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
27 #define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->resource.wineD3DDevice)->wineD3D))->gl_info
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,
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}
53 static const Wined3dTextureStateMap textureObjectTextureStates[] = {
54 {WINED3DTSS_ADDRESSW , WINED3DTSS_ADDRESSW},
55 {-1, 0}
58 /* *******************************************
59 IWineD3DBaseTexture IUnknown parts follow
60 ******************************************* */
61 HRESULT WINAPI IWineD3DBaseTextureImpl_QueryInterface(IWineD3DBaseTexture *iface, REFIID riid, LPVOID *ppobj)
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 S_OK;
73 *ppobj = NULL;
74 return E_NOINTERFACE;
77 ULONG WINAPI IWineD3DBaseTextureImpl_AddRef(IWineD3DBaseTexture *iface) {
78 IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
79 ULONG ref = InterlockedIncrement(&This->resource.ref);
81 TRACE("(%p) : AddRef increasing from %ld\n", This,ref - 1);
82 return ref;
85 ULONG WINAPI IWineD3DBaseTextureImpl_Release(IWineD3DBaseTexture *iface) {
86 IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
87 ULONG ref = InterlockedDecrement(&This->resource.ref);
88 TRACE("(%p) : Releasing from %ld\n", This, ref + 1);
89 if (ref == 0) {
90 IWineD3DBaseTextureImpl_CleanUp(iface);
91 HeapFree(GetProcessHeap(), 0, This);
93 return ref;
96 /* class static */
97 void IWineD3DBaseTextureImpl_CleanUp(IWineD3DBaseTexture *iface) {
98 IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
99 TRACE("(%p) : textureName(%d)\n", This, This->baseTexture.textureName);
100 if (This->baseTexture.textureName != 0) {
101 ENTER_GL();
102 TRACE("(%p) : Deleting texture %d\n", This, This->baseTexture.textureName);
103 glDeleteTextures(1, &This->baseTexture.textureName);
104 LEAVE_GL();
106 IWineD3DResourceImpl_CleanUp((IWineD3DResource *)iface);
109 /* ****************************************************
110 IWineD3DBaseTexture IWineD3DResource parts follow
111 **************************************************** */
112 HRESULT WINAPI IWineD3DBaseTextureImpl_GetDevice(IWineD3DBaseTexture *iface, IWineD3DDevice** ppDevice) {
113 return IWineD3DResourceImpl_GetDevice((IWineD3DResource *)iface, ppDevice);
116 HRESULT WINAPI IWineD3DBaseTextureImpl_SetPrivateData(IWineD3DBaseTexture *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
117 return IWineD3DResourceImpl_SetPrivateData((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
120 HRESULT WINAPI IWineD3DBaseTextureImpl_GetPrivateData(IWineD3DBaseTexture *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
121 return IWineD3DResourceImpl_GetPrivateData((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
124 HRESULT WINAPI IWineD3DBaseTextureImpl_FreePrivateData(IWineD3DBaseTexture *iface, REFGUID refguid) {
125 return IWineD3DResourceImpl_FreePrivateData((IWineD3DResource *)iface, refguid);
128 DWORD WINAPI IWineD3DBaseTextureImpl_SetPriority(IWineD3DBaseTexture *iface, DWORD PriorityNew) {
129 return IWineD3DResourceImpl_SetPriority((IWineD3DResource *)iface, PriorityNew);
132 DWORD WINAPI IWineD3DBaseTextureImpl_GetPriority(IWineD3DBaseTexture *iface) {
133 return IWineD3DResourceImpl_GetPriority((IWineD3DResource *)iface);
136 void WINAPI IWineD3DBaseTextureImpl_PreLoad(IWineD3DBaseTexture *iface) {
137 return IWineD3DResourceImpl_PreLoad((IWineD3DResource *)iface);
140 WINED3DRESOURCETYPE WINAPI IWineD3DBaseTextureImpl_GetType(IWineD3DBaseTexture *iface) {
141 return IWineD3DResourceImpl_GetType((IWineD3DResource *)iface);
144 HRESULT WINAPI IWineD3DBaseTextureImpl_GetParent(IWineD3DBaseTexture *iface, IUnknown **pParent) {
145 return IWineD3DResourceImpl_GetParent((IWineD3DResource *)iface, pParent);
148 /* ******************************************************
149 IWineD3DBaseTexture IWineD3DBaseTexture parts follow
150 ****************************************************** */
152 /* There is no OpenGL equivilent of setLOD, getLOD, all they do it priortise testure loading
153 * so just pretend that they work unless something really needs a failure. */
154 DWORD WINAPI IWineD3DBaseTextureImpl_SetLOD(IWineD3DBaseTexture *iface, DWORD LODNew) {
155 IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
157 if (This->resource.pool != WINED3DPOOL_MANAGED) {
158 return WINED3DERR_INVALIDCALL;
161 if(LODNew >= This->baseTexture.levels)
162 LODNew = This->baseTexture.levels - 1;
163 This->baseTexture.LOD = LODNew;
165 TRACE("(%p) : set bogus LOD to %d\n", This, This->baseTexture.LOD);
167 return This->baseTexture.LOD;
170 DWORD WINAPI IWineD3DBaseTextureImpl_GetLOD(IWineD3DBaseTexture *iface) {
171 IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
173 if (This->resource.pool != WINED3DPOOL_MANAGED) {
174 return WINED3DERR_INVALIDCALL;
177 TRACE("(%p) : returning %d\n", This, This->baseTexture.LOD);
179 return This->baseTexture.LOD;
182 DWORD WINAPI IWineD3DBaseTextureImpl_GetLevelCount(IWineD3DBaseTexture *iface) {
183 IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
184 TRACE("(%p) : returning %d\n", This, This->baseTexture.levels);
185 return This->baseTexture.levels;
188 HRESULT WINAPI IWineD3DBaseTextureImpl_SetAutoGenFilterType(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) {
189 IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
191 if (!(This->baseTexture.usage & WINED3DUSAGE_AUTOGENMIPMAP)) {
192 TRACE("(%p) : returning invalid call\n", This);
193 return WINED3DERR_INVALIDCALL;
195 This->baseTexture.filterType = FilterType;
196 TRACE("(%p) :\n", This);
197 return WINED3D_OK;
200 WINED3DTEXTUREFILTERTYPE WINAPI IWineD3DBaseTextureImpl_GetAutoGenFilterType(IWineD3DBaseTexture *iface) {
201 IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
202 FIXME("(%p) : stub\n", This);
203 if (!(This->baseTexture.usage & WINED3DUSAGE_AUTOGENMIPMAP)) {
204 return WINED3DTEXF_NONE;
206 return This->baseTexture.filterType;
209 void WINAPI IWineD3DBaseTextureImpl_GenerateMipSubLevels(IWineD3DBaseTexture *iface) {
210 IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
211 /* TODO: implement filters using GL_SGI_generate_mipmaps http://oss.sgi.com/projects/ogl-sample/registry/SGIS/generate_mipmap.txt */
212 FIXME("(%p) : stub\n", This);
213 return ;
216 /* Internal function, No d3d mapping */
217 BOOL WINAPI IWineD3DBaseTextureImpl_SetDirty(IWineD3DBaseTexture *iface, BOOL dirty) {
218 BOOL old;
219 IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
220 old = This->baseTexture.dirty;
221 This->baseTexture.dirty = dirty;
222 return old;
225 BOOL WINAPI IWineD3DBaseTextureImpl_GetDirty(IWineD3DBaseTexture *iface) {
226 IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
227 return This->baseTexture.dirty;
230 HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface) {
231 IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
232 HRESULT hr = WINED3D_OK;
233 UINT textureDimensions;
234 BOOL isNewTexture = FALSE;
235 TRACE("(%p) : About to bind texture\n", This);
237 textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
238 ENTER_GL();
239 #if 0 /* TODO: context manager support */
240 IWineD3DContextManager_PushState(This->contextManager, textureDimensions, ENABLED, NOW /* make sure the state is applied now */);
241 #else
242 glEnable(textureDimensions);
243 #endif
245 /* Generate a texture name if we don't already have one */
246 if (This->baseTexture.textureName == 0) {
247 glGenTextures(1, &This->baseTexture.textureName);
248 checkGLcall("glGenTextures");
249 TRACE("Generated texture %d\n", This->baseTexture.textureName);
250 if (This->resource.pool == WINED3DPOOL_DEFAULT) {
251 /* Tell opengl to try and keep this texture in video ram (well mostly) */
252 GLclampf tmp;
253 tmp = 0.9f;
254 glPrioritizeTextures(1, &This->baseTexture.textureName, &tmp);
257 /* Initialise the state of the texture object
258 to the openGL defaults, not the directx defaults */
259 This->baseTexture.states[WINED3DTEXSTA_ADDRESSU] = D3DTADDRESS_WRAP;
260 This->baseTexture.states[WINED3DTEXSTA_ADDRESSV] = D3DTADDRESS_WRAP;
261 This->baseTexture.states[WINED3DTEXSTA_ADDRESSW] = D3DTADDRESS_WRAP;
262 This->baseTexture.states[WINED3DTEXSTA_BORDERCOLOR] = 0;
263 This->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_LINEAR;
264 This->baseTexture.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */
265 This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */
266 This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] = 0;
267 This->baseTexture.states[WINED3DTEXSTA_MAXANISOTROPY] = 0;
268 This->baseTexture.states[WINED3DTEXSTA_SRGBTEXTURE] = 0;
269 This->baseTexture.states[WINED3DTEXSTA_ELEMENTINDEX] = 0;
270 This->baseTexture.states[WINED3DTEXSTA_DMAPOFFSET] = 0;
271 This->baseTexture.states[WINED3DTEXSTA_TSSADDRESSW] = D3DTADDRESS_WRAP;
272 IWineD3DBaseTexture_SetDirty(iface, TRUE);
273 isNewTexture = TRUE;
276 /* Bind the texture */
277 if (This->baseTexture.textureName != 0) {
278 glBindTexture(textureDimensions, This->baseTexture.textureName);
279 checkGLcall("glBindTexture");
280 if (isNewTexture) {
281 /* For a new texture we have to set the textures levels after binding the texture,
282 * in theory this is all we should ever have to dom, but because ATI's drivers are broken we
283 * also need to set the texture dimensins before the texture is is set */
284 TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1);
285 glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1);
286 checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels)");
289 } else { /* this only happened if we've run out of openGL textures */
290 WARN("This texture doesn't have an openGL texture assigned to it\n");
291 hr = WINED3DERR_INVALIDCALL;
294 LEAVE_GL();
295 return hr;
298 HRESULT WINAPI IWineD3DBaseTextureImpl_UnBindTexture(IWineD3DBaseTexture *iface) {
299 IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
300 UINT textureDimensions;
302 TRACE("(%p) : About to bind texture\n", This);
303 textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
305 ENTER_GL();
307 glBindTexture(textureDimensions, 0);
308 #if 0 /* TODO: context manager support */
309 IWineD3DContextManager_PopState(This->contextManager, textureDimensions, ENABLED, NOW /* make sure the state is applied now */);
310 #else
311 glDisable(textureDimensions);
312 #endif
314 LEAVE_GL();
315 return WINED3D_OK;
318 UINT WINAPI IWineD3DBaseTextureImpl_GetTextureDimensions(IWineD3DBaseTexture *iface){
319 IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
320 FIXME("(%p) : This shouldn't be called\n", This);
321 return WINED3D_OK;
324 static inline GLenum warpLookupType(WINED3DSAMPLERSTATETYPE Type) {
325 switch(Type) {
326 case WINED3DSAMP_ADDRESSU:
327 return GL_TEXTURE_WRAP_S;
328 case WINED3DSAMP_ADDRESSV:
329 return GL_TEXTURE_WRAP_T;
330 case WINED3DSAMP_ADDRESSW:
331 return GL_TEXTURE_WRAP_R;
332 default:
333 FIXME("Unexpected warp type %d\n", Type);
334 return 0;
338 void WINAPI IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface,
339 const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
340 const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
341 IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
342 int i;
343 DWORD *state = This->baseTexture.states;
344 GLint textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
345 IWineD3DBaseTexture_PreLoad(iface);
346 /* run through a couple of loops and apply and states that are different */
347 /* this will reduce the number of texture state changes to an absolute minimum
348 for multi-parameter states we pickup the first one that changes, work out the correct values for the other states
349 and set all the states that we've just applied to their new values */
351 for (i = 0 ;textureObjectSamplerStates[i].state != -1; i++) {
352 if (*state != samplerStates[textureObjectSamplerStates[i].state]) {
353 /* apply the state */
354 TRACE("(%p) : Changing state %u from %ld to %ld\n", This, i, *state , samplerStates[textureObjectSamplerStates[i].state]);
355 switch (textureObjectSamplerStates[i].function) {
356 case WINED3DSAMP_ADDRESSU:
357 case WINED3DSAMP_ADDRESSV: /* fall through */
358 case WINED3DSAMP_ADDRESSW: /* fall through */
359 *state = samplerStates[textureObjectSamplerStates[i].state];
360 if (*state < minLookup[WINELOOKUP_WARPPARAM] || *state > maxLookup[WINELOOKUP_WARPPARAM]) {
361 FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", *state, textureObjectSamplerStates[i].function);
362 } else {
363 GLint wrapParm = stateLookup[WINELOOKUP_WARPPARAM][*state - minLookup[WINELOOKUP_WARPPARAM]];
364 TRACE("Setting WRAP_R to %d for %x\n", wrapParm, textureDimensions);
365 glTexParameteri(textureDimensions, warpLookupType(textureObjectSamplerStates[i].function), wrapParm);
366 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
368 break;
369 case WINED3DSAMP_BORDERCOLOR:
371 float col[4];
372 *state = samplerStates[textureObjectSamplerStates[i].state];
373 D3DCOLORTOGLFLOAT4(*state, col);
374 TRACE("Setting border color for %u to %lx\n", textureDimensions, *state);
375 glTexParameterfv(textureDimensions, GL_TEXTURE_BORDER_COLOR, &col[0]);
376 checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
378 break;
379 case WINED3DSAMP_MAGFILTER:
381 GLint glValue;
382 *state = samplerStates[textureObjectSamplerStates[i].state];
383 if (*state < minLookup[WINELOOKUP_MAGFILTER] || *state > maxLookup[WINELOOKUP_MAGFILTER]) {
384 FIXME("Unrecognized or unsupported MAGFILTER* value %ld, state %d\n", *state, textureObjectSamplerStates[i].function);
386 glValue = stateLookup[WINELOOKUP_MAGFILTER][*state - minLookup[WINELOOKUP_MAGFILTER]];
387 TRACE("ValueMAG=%ld setting MAGFILTER to %x\n", *state, glValue);
388 glTexParameteri(textureDimensions, GL_TEXTURE_MAG_FILTER, glValue);
389 /* 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. */
390 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && WINED3DTEXF_ANISOTROPIC == *state) {
391 glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);
394 break;
396 case WINED3DSAMP_MINFILTER:
397 This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] = samplerStates[WINED3DSAMP_MIPFILTER];
398 case WINED3DSAMP_MIPFILTER: /* fall through */
400 GLint glValue;
401 *state = samplerStates[textureObjectSamplerStates[i].state];
402 if (This->baseTexture.states[WINED3DTEXSTA_MINFILTER] < WINED3DTEXF_NONE ||
403 This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] < WINED3DTEXF_NONE ||
404 This->baseTexture.states[WINED3DTEXSTA_MINFILTER] > WINED3DTEXF_ANISOTROPIC ||
405 This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] > WINED3DTEXF_LINEAR)
408 FIXME("Unrecognized or unsupported D3DSAMP_MINFILTER value %ld, state %d D3DSAMP_MIPFILTER value %ld, state %d\n",
409 This->baseTexture.states[WINED3DTEXSTA_MINFILTER],
410 textureObjectSamplerStates[WINED3DTEXSTA_MINFILTER].function,
411 This->baseTexture.states[WINED3DTEXSTA_MIPFILTER],
412 textureObjectSamplerStates[WINED3DTEXSTA_MIPFILTER].function);
414 glValue = minMipLookup[min(max(This->baseTexture.states[WINED3DTEXSTA_MINFILTER],WINED3DTEXF_NONE), WINED3DTEXF_ANISOTROPIC)]
415 [min(max(This->baseTexture.states[WINED3DTEXSTA_MIPFILTER],WINED3DTEXF_NONE), WINED3DTEXF_LINEAR)];
417 TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n",
418 This->baseTexture.states[WINED3DTEXSTA_MINFILTER],
419 This->baseTexture.states[WINED3DTEXSTA_MIPFILTER], glValue);
420 glTexParameteri(textureDimensions, GL_TEXTURE_MIN_FILTER, glValue);
421 checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
423 break;
424 case WINED3DSAMP_MAXMIPLEVEL:
425 *state = samplerStates[textureObjectSamplerStates[i].state];
427 * Not really the same, but the more apprioprate than nothing
429 glTexParameteri(textureDimensions, GL_TEXTURE_BASE_LEVEL, *state);
430 break;
431 case WINED3DSAMP_MAXANISOTROPY:
432 *state = samplerStates[textureObjectSamplerStates[i].state];
433 glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, *state);
434 checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ...");
435 break;
436 case WINED3DFUNC_UNIMPLEMENTED: /* unimplemented */
437 TRACE("(%p) : stub\n", This);
438 *state = samplerStates[textureObjectSamplerStates[i].state];
439 break;
440 case WINED3DFUNC_NOTSUPPORTED: /* nop */
441 TRACE("(%p) : %s function is not supported by this opengl implementation\n", This, "unknown" /* TODO: replace with debug_blah... */);
442 *state = samplerStates[textureObjectSamplerStates[i].state];
443 break;
446 state++;
449 for(i = 0 ;textureObjectTextureStates[i].state != - 1; i++) {
450 if(*state != textureStates[textureObjectTextureStates[i].state] ) {
451 /* apply the state */
452 *state = textureStates[textureObjectTextureStates[i].state];
453 switch (textureObjectTextureStates[i].function) {
454 case WINED3DTSS_ADDRESSW:
455 /* I'm not sure what to do if this is set as well as ADDRESSW on the sampler, how do they interact together? */
456 break;
457 case WINED3DFUNC_UNIMPLEMENTED: /* unimplemented */
458 TRACE("(%p) : stub\n", This);
459 break;
460 case WINED3DFUNC_NOTSUPPORTED: /* nop */
461 TRACE("(%p) : function no supported by this opengl implementation\n", This);
462 break;
465 state++;
470 static const IWineD3DBaseTextureVtbl IWineD3DBaseTexture_Vtbl =
472 /* IUnknown */
473 IWineD3DBaseTextureImpl_QueryInterface,
474 IWineD3DBaseTextureImpl_AddRef,
475 IWineD3DBaseTextureImpl_Release,
476 /* IWineD3DResource */
477 IWineD3DBaseTextureImpl_GetParent,
478 IWineD3DBaseTextureImpl_GetDevice,
479 IWineD3DBaseTextureImpl_SetPrivateData,
480 IWineD3DBaseTextureImpl_GetPrivateData,
481 IWineD3DBaseTextureImpl_FreePrivateData,
482 IWineD3DBaseTextureImpl_SetPriority,
483 IWineD3DBaseTextureImpl_GetPriority,
484 IWineD3DBaseTextureImpl_PreLoad,
485 IWineD3DBaseTextureImpl_GetType,
486 /*IWineD3DBaseTexture*/
487 IWineD3DBaseTextureImpl_SetLOD,
488 IWineD3DBaseTextureImpl_GetLOD,
489 IWineD3DBaseTextureImpl_GetLevelCount,
490 IWineD3DBaseTextureImpl_SetAutoGenFilterType,
491 IWineD3DBaseTextureImpl_GetAutoGenFilterType,
492 IWineD3DBaseTextureImpl_GenerateMipSubLevels,
493 IWineD3DBaseTextureImpl_SetDirty,
494 IWineD3DBaseTextureImpl_GetDirty,
495 /* internal */
496 IWineD3DBaseTextureImpl_BindTexture,
497 IWineD3DBaseTextureImpl_UnBindTexture,
498 IWineD3DBaseTextureImpl_GetTextureDimensions,
499 IWineD3DBaseTextureImpl_ApplyStateChanges