2 * IWineD3DDevice implementation
4 * Copyright 2002-2005 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "wined3d_private.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
28 WINE_DECLARE_DEBUG_CHANNEL(d3d_caps
);
29 WINE_DECLARE_DEBUG_CHANNEL(d3d_fps
);
30 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader
);
31 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
34 #define D3DMEMCHECK(object, ppResult) if(NULL == object){ *ppResult = NULL; WARN("Out of memory\n"); return D3DERR_OUTOFVIDEOMEMORY;}
36 #define D3DCREATEOBJECTINSTANCE(object, type){ \
37 object=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3D##type##Impl)); \
38 D3DMEMCHECK(object, pp##type); \
39 object->lpVtbl = &IWineD3D##type##_Vtbl; \
40 object->wineD3DDevice = This; \
41 object->parent = parent; \
43 *pp##type = (IWineD3D##type *) object; \
46 #define D3DCREATERESOURCEOBJECTINSTANCE(object, type, d3dtype){ \
47 object=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3D##type##Impl)); \
48 D3DMEMCHECK(object, pp##type); \
49 object->lpVtbl = &IWineD3D##type##_Vtbl; \
50 object->resource.wineD3DDevice = This; \
51 object->resource.parent = parent; \
52 object->resource.resourceType = d3dtype; \
53 object->resource.ref = 1; \
54 object->resource.pool = Pool; \
55 object->resource.format = Format; \
56 object->resource.usage = Usage; \
57 object->resource.size = 0; \
58 object->resource.allocatedMemory = 0; \
59 *pp##type = (IWineD3D##type *) object; \
62 #define D3DINITILIZEBASETEXTURE(_basetexture) { \
63 _basetexture.levels = Levels; \
64 _basetexture.filterType = (Usage & D3DUSAGE_AUTOGENMIPMAP) ? D3DTEXF_LINEAR : D3DTEXF_NONE; \
65 _basetexture.LOD = 0; \
68 /**********************************************************
69 * Global variable / Constants follow
70 **********************************************************/
71 const float identity
[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1}; /* When needed for comparisons */
73 /**********************************************************
74 * Utility functions follow
75 **********************************************************/
76 /* Convert the D3DLIGHT properties into equivalent gl lights */
77 void setup_light(IWineD3DDevice
*iface
, LONG Index
, PLIGHTINFOEL
*lightInfo
) {
80 float colRGBA
[] = {0.0, 0.0, 0.0, 0.0};
81 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
83 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
84 glMatrixMode(GL_MODELVIEW
);
86 glLoadMatrixf((float *) &This
->stateBlock
->transforms
[D3DTS_VIEW
].u
.m
[0][0]);
89 colRGBA
[0] = lightInfo
->OriginalParms
.Diffuse
.r
;
90 colRGBA
[1] = lightInfo
->OriginalParms
.Diffuse
.g
;
91 colRGBA
[2] = lightInfo
->OriginalParms
.Diffuse
.b
;
92 colRGBA
[3] = lightInfo
->OriginalParms
.Diffuse
.a
;
93 glLightfv(GL_LIGHT0
+Index
, GL_DIFFUSE
, colRGBA
);
94 checkGLcall("glLightfv");
97 colRGBA
[0] = lightInfo
->OriginalParms
.Specular
.r
;
98 colRGBA
[1] = lightInfo
->OriginalParms
.Specular
.g
;
99 colRGBA
[2] = lightInfo
->OriginalParms
.Specular
.b
;
100 colRGBA
[3] = lightInfo
->OriginalParms
.Specular
.a
;
101 glLightfv(GL_LIGHT0
+Index
, GL_SPECULAR
, colRGBA
);
102 checkGLcall("glLightfv");
105 colRGBA
[0] = lightInfo
->OriginalParms
.Ambient
.r
;
106 colRGBA
[1] = lightInfo
->OriginalParms
.Ambient
.g
;
107 colRGBA
[2] = lightInfo
->OriginalParms
.Ambient
.b
;
108 colRGBA
[3] = lightInfo
->OriginalParms
.Ambient
.a
;
109 glLightfv(GL_LIGHT0
+Index
, GL_AMBIENT
, colRGBA
);
110 checkGLcall("glLightfv");
112 /* Attenuation - Are these right? guessing... */
113 glLightf(GL_LIGHT0
+Index
, GL_CONSTANT_ATTENUATION
, lightInfo
->OriginalParms
.Attenuation0
);
114 checkGLcall("glLightf");
115 glLightf(GL_LIGHT0
+Index
, GL_LINEAR_ATTENUATION
, lightInfo
->OriginalParms
.Attenuation1
);
116 checkGLcall("glLightf");
118 quad_att
= 1.4/(lightInfo
->OriginalParms
.Range
*lightInfo
->OriginalParms
.Range
);
119 if (quad_att
< lightInfo
->OriginalParms
.Attenuation2
) quad_att
= lightInfo
->OriginalParms
.Attenuation2
;
120 glLightf(GL_LIGHT0
+Index
, GL_QUADRATIC_ATTENUATION
, quad_att
);
121 checkGLcall("glLightf");
123 switch (lightInfo
->OriginalParms
.Type
) {
126 glLightfv(GL_LIGHT0
+Index
, GL_POSITION
, &lightInfo
->lightPosn
[0]);
127 checkGLcall("glLightfv");
128 glLightf(GL_LIGHT0
+ Index
, GL_SPOT_CUTOFF
, lightInfo
->cutoff
);
129 checkGLcall("glLightf");
135 glLightfv(GL_LIGHT0
+Index
, GL_POSITION
, &lightInfo
->lightPosn
[0]);
136 checkGLcall("glLightfv");
138 glLightfv(GL_LIGHT0
+Index
, GL_SPOT_DIRECTION
, &lightInfo
->lightDirn
[0]);
139 checkGLcall("glLightfv");
140 glLightf(GL_LIGHT0
+ Index
, GL_SPOT_EXPONENT
, lightInfo
->exponent
);
141 checkGLcall("glLightf");
142 glLightf(GL_LIGHT0
+ Index
, GL_SPOT_CUTOFF
, lightInfo
->cutoff
);
143 checkGLcall("glLightf");
147 case D3DLIGHT_DIRECTIONAL
:
149 glLightfv(GL_LIGHT0
+Index
, GL_POSITION
, &lightInfo
->lightPosn
[0]); /* Note gl uses w position of 0 for direction! */
150 checkGLcall("glLightfv");
151 glLightf(GL_LIGHT0
+Index
, GL_SPOT_CUTOFF
, lightInfo
->cutoff
);
152 checkGLcall("glLightf");
153 glLightf(GL_LIGHT0
+Index
, GL_SPOT_EXPONENT
, 0.0f
);
154 checkGLcall("glLightf");
158 FIXME("Unrecognized light type %d\n", lightInfo
->OriginalParms
.Type
);
161 /* Restore the modelview matrix */
165 /* Apply the current values to the specified texture stage */
166 void WINAPI
IWineD3DDeviceImpl_SetupTextureStates(IWineD3DDevice
*iface
, DWORD Stage
, DWORD Flags
) {
167 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
170 BOOL changeTexture
= TRUE
;
172 TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage
);
173 for (i
= 1; i
< HIGHEST_TEXTURE_STATE
; i
++) {
178 /* Performance: For texture states where multiples effect the outcome, only bother
179 applying the last one as it will pick up all the other values */
180 case D3DTSS_COLORARG0
: /* Will be picked up when setting color op */
181 case D3DTSS_COLORARG1
: /* Will be picked up when setting color op */
182 case D3DTSS_COLORARG2
: /* Will be picked up when setting color op */
183 case D3DTSS_ALPHAARG0
: /* Will be picked up when setting alpha op */
184 case D3DTSS_ALPHAARG1
: /* Will be picked up when setting alpha op */
185 case D3DTSS_ALPHAARG2
: /* Will be picked up when setting alpha op */
189 /* Performance: If the texture states only impact settings for the texture unit
190 (compared to the texture object) then there is no need to reapply them. The
191 only time they need applying is the first time, since we cheat and put the
192 values into the stateblock without applying.
193 Per-texture unit: texture function (eg. combine), ops and args
195 texture generation settings
196 Note: Due to some special conditions there may be a need to do particular ones
197 of these, which is what the Flags allows */
199 case D3DTSS_TEXCOORDINDEX
:
200 if (!(Flags
== REAPPLY_ALL
)) skip
=TRUE
;
204 if (!(Flags
& REAPPLY_ALPHAOP
)) skip
=TRUE
;
212 /* Performance: Only change to this texture if we have to */
214 /* Make appropriate texture active */
215 if (GL_SUPPORT(ARB_MULTITEXTURE
)) {
216 GLACTIVETEXTURE(Stage
);
217 } else if (Stage
> 0) {
218 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
220 changeTexture
= FALSE
;
223 /* Now apply the change */
224 IWineD3DDevice_SetTextureStageState(iface
, Stage
, i
, This
->stateBlock
->textureState
[Stage
][i
]);
228 /* Note the D3DRS value applies to all textures, but GL has one
229 * per texture, so apply it now ready to be used!
231 D3DCOLORTOGLFLOAT4(This
->stateBlock
->renderState
[WINED3DRS_TEXTUREFACTOR
], col
);
232 glTexEnvfv(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_COLOR
, &col
[0]);
233 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
235 TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage
);
238 /**********************************************************
239 * IUnknown parts follows
240 **********************************************************/
242 HRESULT WINAPI
IWineD3DDeviceImpl_QueryInterface(IWineD3DDevice
*iface
,REFIID riid
,LPVOID
*ppobj
)
244 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
245 /* FIXME: This needs to extend an IWineD3DBaseObject */
247 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
248 if (IsEqualGUID(riid
, &IID_IUnknown
)
249 || IsEqualGUID(riid
, &IID_IWineD3DDevice
)) {
250 IUnknown_AddRef(iface
);
255 return E_NOINTERFACE
;
258 ULONG WINAPI
IWineD3DDeviceImpl_AddRef(IWineD3DDevice
*iface
) {
259 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
260 ULONG refCount
= InterlockedIncrement(&This
->ref
);
262 TRACE("(%p) : AddRef increasing from %ld\n", This
, refCount
- 1);
266 ULONG WINAPI
IWineD3DDeviceImpl_Release(IWineD3DDevice
*iface
) {
267 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
268 ULONG refCount
= InterlockedDecrement(&This
->ref
);
270 TRACE("(%p) : Releasing from %ld\n", This
, refCount
+ 1);
273 /* TODO: Clean up all the surfaces and textures! */
274 /* FIXME: Create targets and state blocks in d3d8 */
275 if (((IWineD3DImpl
*)This
->wineD3D
)->dxVersion
> 8) { /*We don't create a state block in d3d8 yet*/
276 /* NOTE: You must release the parent if the objects was created via a callback
277 ** ***************************/
278 IWineD3DStateBlock_Release((IWineD3DStateBlock
*)This
->stateBlock
);
280 IWineD3D_Release(This
->wineD3D
);
281 HeapFree(GetProcessHeap(), 0, This
);
286 /**********************************************************
287 * IWineD3DDevice implementation follows
288 **********************************************************/
289 HRESULT WINAPI
IWineD3DDeviceImpl_GetParent(IWineD3DDevice
*iface
, IUnknown
**pParent
) {
290 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
291 *pParent
= This
->parent
;
292 IUnknown_AddRef(This
->parent
);
296 HRESULT WINAPI
IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice
*iface
, UINT Size
, DWORD Usage
,
297 DWORD FVF
, D3DPOOL Pool
, IWineD3DVertexBuffer
** ppVertexBuffer
, HANDLE
*sharedHandle
,
299 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
300 IWineD3DVertexBufferImpl
*object
;
301 WINED3DFORMAT Format
= WINED3DFMT_VERTEXDATA
; /* Dummy format for now */
302 D3DCREATERESOURCEOBJECTINSTANCE(object
, VertexBuffer
, D3DRTYPE_VERTEXBUFFER
)
304 object
->resource
.size
= Size
;
305 object
->resource
.allocatedMemory
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, object
->resource
.size
);
308 TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This
, Size
, Usage
, FVF
, Pool
, object
->resource
.allocatedMemory
, object
);
309 *ppVertexBuffer
= (IWineD3DVertexBuffer
*)object
;
314 HRESULT WINAPI
IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice
*iface
, UINT Length
, DWORD Usage
,
315 WINED3DFORMAT Format
, D3DPOOL Pool
, IWineD3DIndexBuffer
** ppIndexBuffer
,
316 HANDLE
*sharedHandle
, IUnknown
*parent
) {
317 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
318 IWineD3DIndexBufferImpl
*object
;
319 TRACE("(%p) Creating index buffer\n", This
);
321 /* Allocate the storage for the device */
322 D3DCREATERESOURCEOBJECTINSTANCE(object
,IndexBuffer
,D3DRTYPE_INDEXBUFFER
)
324 object
->resource
.size
= Length
;
325 object
->resource
.allocatedMemory
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,object
->resource
.size
);
327 TRACE("(%p) : Len=%d, Use=%lx, Format=(%u,%s), Pool=%d - Memory@%p, Iface@%p\n", This
, Length
, Usage
, Format
,
328 debug_d3dformat(Format
), Pool
, object
, object
->resource
.allocatedMemory
);
329 *ppIndexBuffer
= (IWineD3DIndexBuffer
*) object
;
334 HRESULT WINAPI
IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice
* iface
, D3DSTATEBLOCKTYPE Type
, IWineD3DStateBlock
** ppStateBlock
, IUnknown
*parent
) {
336 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
337 IWineD3DStateBlockImpl
*object
;
339 D3DCREATEOBJECTINSTANCE(object
, StateBlock
)
340 object
->blockType
= Type
;
342 /* Special case - Used during initialization to produce a placeholder stateblock
343 so other functions called can update a state block */
344 if (Type
== (D3DSTATEBLOCKTYPE
) 0) {
345 /* Don't bother increasing the reference count otherwise a device will never
346 be freed due to circular dependencies */
350 /* Otherwise, might as well set the whole state block to the appropriate values */
351 IWineD3DDevice_AddRef(iface
);
352 memcpy(object
, This
->stateBlock
, sizeof(IWineD3DStateBlockImpl
));
353 FIXME("unfinished - needs to set up changed and set attributes\n");
358 /* ************************************
360 [in] Render targets are not lockable unless the application specifies TRUE for Lockable. Note that lockable render targets reduce performance on some graphics hardware.
363 [in] Set this flag to TRUE to enable z-buffer discarding, and FALSE otherwise.
365 If this flag is set, the contents of the depth stencil buffer will be invalid after calling either IDirect3DDevice9::Present or IDirect3DDevice9::SetDepthStencilSurface with a different depth surface.
367 ******************************** */
369 HRESULT WINAPI
IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice
*iface
, UINT Width
, UINT Height
, WINED3DFORMAT Format
, BOOL Lockable
, BOOL Discard
, UINT Level
, IWineD3DSurface
**ppSurface
,D3DRESOURCETYPE Type
, DWORD Usage
, D3DPOOL Pool
, D3DMULTISAMPLE_TYPE MultiSample
,DWORD MultisampleQuality
, HANDLE
* pSharedHandle
, IUnknown
*parent
) {
370 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
371 IWineD3DSurfaceImpl
*object
; /*NOTE: impl ref allowed since this is a create function */
372 unsigned int pow2Width
, pow2Height
;
374 TRACE("(%p) Create surface\n",This
);
376 /** FIXME: Check ranges on the inputs are valid
379 * [in] Quality level. The valid range is between zero and one less than the level
380 * returned by pQualityLevels used by IDirect3D9::CheckDeviceMultiSampleType.
381 * Passing a larger value returns the error D3DERR_INVALIDCALL. The MultisampleQuality
382 * values of paired render targets, depth stencil surfaces, and the MultiSample type
384 *******************************/
389 * [in] Set this flag to TRUE to enable z-buffer discarding, and FALSE otherwise.
391 * If this flag is set, the contents of the depth stencil buffer will be
392 * invalid after calling either IDirect3DDevice9::Present or * IDirect3DDevice9::SetDepthStencilSurface
393 * with a different depth surface.
395 *This flag has the same behavior as the constant, D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL, in D3DPRESENTFLAG.
396 ***************************/
398 if(MultisampleQuality
< 0) {
399 FIXME("Invalid multisample level %ld \n", MultisampleQuality
);
400 return D3DERR_INVALIDCALL
; /* TODO: Check that this is the case! */
403 if(MultisampleQuality
> 0){
404 FIXME("MultisampleQuality set to %ld, bstituting 0 \n" , MultisampleQuality
);
405 MultisampleQuality
=0;
408 /* Non-power2 support */
410 /* Find the nearest pow2 match */
411 pow2Width
= pow2Height
= 1;
412 while (pow2Width
< Width
) pow2Width
<<= 1;
413 while (pow2Height
< Height
) pow2Height
<<= 1;
415 /* TODO: support for non-power 2 textures */
416 if(pow2Width
> Width
|| pow2Height
> Height
){
417 /** TODO: add support for non power two compressed textures (OpenGL provices support for * non-power-two textures gratis) **/
418 return D3DERR_NOTAVAILABLE
;
422 /** TODO: Check against the maximum texture sizes supported by the video card **/
424 D3DCREATERESOURCEOBJECTINSTANCE(object
,Surface
,D3DRTYPE_SURFACE
)
425 object
->container
= (IUnknown
*) This
;
427 object
->currentDesc
.Width
= Width
;
428 object
->currentDesc
.Height
= Height
;
429 object
->currentDesc
.Level
= Level
;
430 object
->currentDesc
.MultiSampleType
= MultiSample
;
431 object
->currentDesc
.MultiSampleQuality
= MultisampleQuality
;
432 object
->discard
= Discard
;
433 object
->bytesPerPixel
= D3DFmtGetBpp(This
, Format
);
435 /** DXTn mipmaps use the same number of 'levels' down to eg. 8x1, but since
436 * it is based around 4x4 pixel blocks it requires padding, so allocate enough
438 *********************************/
439 if (Format
== WINED3DFMT_DXT1
) {
440 /* DXT1 is half byte per pixel */
441 object
->resource
.size
= ((max(Width
,4) * object
->bytesPerPixel
) * max(Height
,4)) / 2;
443 } else if (Format
== WINED3DFMT_DXT2
|| Format
== WINED3DFMT_DXT3
||
444 Format
== WINED3DFMT_DXT4
|| Format
== WINED3DFMT_DXT5
) {
445 object
->resource
.size
= ((max(Width
,4) * object
->bytesPerPixel
) * max(Height
,4));
447 object
->resource
.size
= (Width
* object
->bytesPerPixel
) * Height
;
450 TRACE("Pool %d %d %d %d",Pool
, D3DPOOL_DEFAULT
, D3DPOOL_MANAGED
, D3DPOOL_SYSTEMMEM
);
453 /* TODO: Check that we have enough video ram left */
454 if(Pool
== D3DPOOL_DEFAULT
&& IWineD3DDevice_GetAvailableTextureMem(iface
) <= object
->currentDesc
.Size
){
455 TRACE("Out of 'bogus' video memory\n");
456 HeapFree(GetProcessHeap(),0,object
);
458 return D3DERR_OUTOFVIDEOMEMORY
;
462 /** Quick lockable sanity check TODO: remove this after surfaces, usage and locablility have been debugged properly
463 * this function is too deap to need to care about things like this.
464 * Levels need to be checked too, and possibly Type wince they all affect what can be done.
465 * ****************************************/
467 case D3DPOOL_SCRATCH
:
468 if(Lockable
== FALSE
)
469 FIXME("Create suface called with a pool of SCRATCH and a Lockable of FALSE \
470 which are mutually exclusive, setting lockable to true\n");
473 case D3DPOOL_SYSTEMMEM
:
474 if(Lockable
== FALSE
) FIXME("Create surface called with a pool of SYSTEMMEM and a Lockable of FALSE, \
475 this is acceptable but unexpected (I can't know how the surface can be usable!)\n");
476 case D3DPOOL_MANAGED
:
477 if(Usage
== D3DUSAGE_DYNAMIC
) FIXME("Create surface called with a pool of MANAGED and a \
478 Usage of DYNAMIC which are mutually exclusive, not doing \
479 anything just telling you.\n");
481 case D3DPOOL_DEFAULT
: /*TODO: Create offscreen plain can cause this check to fail..., find out if it should */
482 if(!(Usage
& D3DUSAGE_DYNAMIC
) && !(Usage
& D3DUSAGE_RENDERTARGET
)
483 && !(Usage
&& D3DUSAGE_DEPTHSTENCIL
) && Lockable
== TRUE
)
484 FIXME("Creating a surface with a POOL of DEFAULT with Locable true, that doesn't specify DYNAMIC usage.\n");
487 FIXME("(%p) Unknown pool %d\n", This
, Pool
);
491 if (Usage
& D3DUSAGE_RENDERTARGET
&& Pool
!= D3DPOOL_DEFAULT
){
492 FIXME("Trying to create a render target that isn't in the default pool\n");
496 object
->locked
= FALSE
;
497 object
->lockable
= (WINED3DFMT_D16_LOCKABLE
== Format
) ? TRUE
: Lockable
;
498 /* TODO: memory management */
499 object
->resource
.allocatedMemory
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,object
->resource
.size
);
500 if(object
->resource
.allocatedMemory
== NULL
) {
501 FIXME("Out of memory!\n");
502 HeapFree(GetProcessHeap(),0,object
);
504 return D3DERR_OUTOFVIDEOMEMORY
;
508 IWineD3DSurface_CleanDirtyRect(*ppSurface
);
509 TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) lockable(%d) surf@%p, surfmem@%p, %d bytes\n",
510 This
, Width
, Height
, Format
, debug_d3dformat(Format
),
511 (WINED3DFMT_D16_LOCKABLE
== Format
), *ppSurface
, object
->resource
.allocatedMemory
, object
->resource
.size
);
516 HRESULT WINAPI
IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice
*iface
, UINT Width
, UINT Height
, UINT Levels
,
517 DWORD Usage
, WINED3DFORMAT Format
, D3DPOOL Pool
,
518 IWineD3DTexture
** ppTexture
, HANDLE
* pSharedHandle
, IUnknown
*parent
,
519 D3DCB_CREATESURFACEFN D3DCB_CreateSurface
) {
521 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
522 IWineD3DTextureImpl
*object
;
528 TRACE("(%p), Width(%d) Height(%d) Levels(%d) Usage(%ld) .... \n", This
, Width
, Height
, Levels
, Usage
);
530 D3DCREATERESOURCEOBJECTINSTANCE(object
, Texture
, D3DRTYPE_TEXTURE
);
531 D3DINITILIZEBASETEXTURE(object
->baseTexture
);
532 object
->width
= Width
;
533 object
->height
= Height
;
535 /* Calculate levels for mip mapping */
537 TRACE("calculating levels %d\n", object
->baseTexture
.levels
);
538 object
->baseTexture
.levels
++;
541 while (tmpW
> 1 && tmpH
> 1) {
542 tmpW
= max(1, tmpW
>> 1);
543 tmpH
= max(1, tmpH
>> 1);
544 object
->baseTexture
.levels
++;
546 TRACE("Calculated levels = %d\n", object
->baseTexture
.levels
);
549 /* Generate all the surfaces */
552 for (i
= 0; i
< object
->baseTexture
.levels
; i
++)
554 /* use the callback to create the texture surface */
555 hr
= D3DCB_CreateSurface(This
->parent
, tmpW
, tmpH
, Format
, Usage
, Pool
, i
, &object
->surfaces
[i
],NULL
);
558 FIXME("Failed to create surface %p \n",object
);
561 IWineD3DSurface_Release(object
->surfaces
[j
]);
563 /* heap free object */
564 HeapFree(GetProcessHeap(),0,object
);
570 IWineD3DSurface_SetContainer(object
->surfaces
[i
], (IUnknown
*)object
);
571 TRACE("Created surface level %d @ %p\n", i
, object
->surfaces
[i
]);
572 /* calculate the next mipmap level */
573 tmpW
= max(1, tmpW
>> 1);
574 tmpH
= max(1, tmpH
>> 1);
577 TRACE("(%p) : Created texture %p\n", This
, object
);
581 HRESULT WINAPI
IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice
*iface
,
582 UINT Width
, UINT Height
, UINT Depth
,
583 UINT Levels
, DWORD Usage
,
584 WINED3DFORMAT Format
, D3DPOOL Pool
,
585 IWineD3DVolumeTexture
** ppVolumeTexture
,
586 HANDLE
* pSharedHandle
, IUnknown
*parent
,
587 D3DCB_CREATEVOLUMEFN D3DCB_CreateVolume
) {
589 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
590 IWineD3DVolumeTextureImpl
*object
;
596 D3DCREATERESOURCEOBJECTINSTANCE(object
, VolumeTexture
, D3DRTYPE_VOLUMETEXTURE
);
597 D3DINITILIZEBASETEXTURE(object
->baseTexture
);
599 TRACE("(%p) : W(%d) H(%d) D(%d), Lvl(%d) Usage(%ld), Fmt(%u,%s), Pool(%s)\n", This
, Width
, Height
,
600 Depth
, Levels
, Usage
, Format
, debug_d3dformat(Format
), debug_d3dpool(Pool
));
602 object
->width
= Width
;
603 object
->height
= Height
;
604 object
->depth
= Depth
;
606 /* Calculate levels for mip mapping */
608 object
->baseTexture
.levels
++;
612 while (tmpW
> 1 && tmpH
> 1 && tmpD
> 1) {
613 tmpW
= max(1, tmpW
>> 1);
614 tmpH
= max(1, tmpH
>> 1);
615 tmpD
= max(1, tmpD
>> 1);
616 object
->baseTexture
.levels
++;
618 TRACE("Calculated levels = %d\n", object
->baseTexture
.levels
);
621 /* Generate all the surfaces */
626 for (i
= 0; i
< object
->baseTexture
.levels
; i
++)
628 /* Create the volume */
629 D3DCB_CreateVolume(This
->parent
, Width
, Height
, Depth
, Format
, Pool
, Usage
,
630 (IWineD3DVolume
**)&object
->volumes
[i
], pSharedHandle
);
631 IWineD3DVolume_SetContainer(object
->volumes
[i
], (IUnknown
*)object
);
633 tmpW
= max(1, tmpW
>> 1);
634 tmpH
= max(1, tmpH
>> 1);
635 tmpD
= max(1, tmpD
>> 1);
638 *ppVolumeTexture
= (IWineD3DVolumeTexture
*) object
;
639 TRACE("(%p) : Created volume texture %p\n", This
, object
);
643 HRESULT WINAPI
IWineD3DDeviceImpl_CreateVolume(IWineD3DDevice
*iface
,
644 UINT Width
, UINT Height
, UINT Depth
,
646 WINED3DFORMAT Format
, D3DPOOL Pool
,
647 IWineD3DVolume
** ppVolume
,
648 HANDLE
* pSharedHandle
, IUnknown
*parent
) {
650 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
651 IWineD3DVolumeImpl
*object
; /** NOTE: impl ref allowed since this is a create function **/
653 D3DCREATERESOURCEOBJECTINSTANCE(object
, Volume
, D3DRTYPE_VOLUME
)
655 TRACE("(%p) : W(%d) H(%d) D(%d), Usage(%ld), Fmt(%u,%s), Pool(%s)\n", This
, Width
, Height
,
656 Depth
, Usage
, Format
, debug_d3dformat(Format
), debug_d3dpool(Pool
));
658 object
->currentDesc
.Width
= Width
;
659 object
->currentDesc
.Height
= Height
;
660 object
->currentDesc
.Depth
= Depth
;
661 object
->bytesPerPixel
= D3DFmtGetBpp(This
, Format
);
663 /** Note: Volume textures cannot be dxtn, hence no need to check here **/
664 object
->resource
.size
= (Width
* object
->bytesPerPixel
) * Height
* Depth
;
665 object
->resource
.allocatedMemory
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, object
->resource
.size
);
666 object
->lockable
= TRUE
;
667 object
->locked
= FALSE
;
668 memset(&object
->lockedBox
, 0, sizeof(D3DBOX
));
669 object
->dirty
= FALSE
;
670 return IWineD3DVolume_CleanDirtyBox((IWineD3DVolume
*) object
);
673 HRESULT WINAPI
IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice
*iface
, UINT EdgeLength
,
674 UINT Levels
, DWORD Usage
,
675 WINED3DFORMAT Format
, D3DPOOL Pool
,
676 IWineD3DCubeTexture
** ppCubeTexture
,
677 HANDLE
* pSharedHandle
, IUnknown
*parent
,
678 D3DCB_CREATESURFACEFN D3DCB_CreateSurface
) {
680 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
681 IWineD3DCubeTextureImpl
*object
; /** NOTE: impl ref allowed since this is a create function **/
686 D3DCREATERESOURCEOBJECTINSTANCE(object
, CubeTexture
, D3DRTYPE_CUBETEXTURE
);
687 D3DINITILIZEBASETEXTURE(object
->baseTexture
);
689 TRACE("(%p) Create Cube Texture \n", This
);
691 object
->edgeLength
= EdgeLength
;
693 /* Calculate levels for mip mapping */
695 object
->baseTexture
.levels
++;
698 tmpW
= max(1, tmpW
/ 2);
699 object
->baseTexture
.levels
++;
701 TRACE("Calculated levels = %d\n", object
->baseTexture
.levels
);
704 /* Generate all the surfaces */
706 for (i
= 0; i
< object
->baseTexture
.levels
; i
++) {
708 /* Create the 6 faces */
709 for (j
= 0; j
< 6; j
++) {
711 hr
=D3DCB_CreateSurface(This
->parent
, tmpW
, tmpW
, Format
, Usage
, Pool
,
712 i
/* Level */, &object
->surfaces
[j
][i
],pSharedHandle
);
719 IWineD3DSurface_Release(object
->surfaces
[j
][i
]);
723 IWineD3DSurface_Release(object
->surfaces
[l
][j
]);
727 FIXME("(%p) Failed to create surface\n",object
);
728 HeapFree(GetProcessHeap(),0,object
);
729 *ppCubeTexture
= NULL
;
732 IWineD3DSurface_SetContainer(object
->surfaces
[j
][i
], (IUnknown
*)object
);
733 TRACE("Created surface level %d @ %p, \n", i
, object
->surfaces
[j
][i
]);
735 tmpW
= max(1, tmpW
>> 1);
738 TRACE("(%p) : Created Cube Texture %p\n", This
, object
);
739 *ppCubeTexture
= (IWineD3DCubeTexture
*) object
;
743 HRESULT WINAPI
IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice
*iface
, WINED3DQUERYTYPE Type
, IWineD3DQuery
**ppQuery
, IUnknown
* parent
){
744 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
745 IWineD3DQueryImpl
*object
; /*NOTE: impl ref allowed since this is a create function */
748 /* Just a check to see if we support this type of query */
749 HRESULT hr
= D3DERR_NOTAVAILABLE
;
750 /* Lie and say everything is good (we can return ok fake data from a stub) */
752 case WINED3DQUERYTYPE_VCACHE
:
753 case WINED3DQUERYTYPE_RESOURCEMANAGER
:
754 case WINED3DQUERYTYPE_VERTEXSTATS
:
755 case WINED3DQUERYTYPE_EVENT
:
756 case WINED3DQUERYTYPE_OCCLUSION
:
757 case WINED3DQUERYTYPE_TIMESTAMP
:
758 case WINED3DQUERYTYPE_TIMESTAMPDISJOINT
:
759 case WINED3DQUERYTYPE_TIMESTAMPFREQ
:
760 case WINED3DQUERYTYPE_PIPELINETIMINGS
:
761 case WINED3DQUERYTYPE_INTERFACETIMINGS
:
762 case WINED3DQUERYTYPE_VERTEXTIMINGS
:
763 case WINED3DQUERYTYPE_PIXELTIMINGS
:
764 case WINED3DQUERYTYPE_BANDWIDTHTIMINGS
:
765 case WINED3DQUERYTYPE_CACHEUTILIZATION
:
769 FIXME("(%p) Unhandled query type %d\n",This
, Type
);
771 FIXME("(%p) : Stub request for query type %d returned %ld\n", This
, Type
, hr
);
775 D3DCREATEOBJECTINSTANCE(object
, Query
)
777 object
->extendedData
= 0;
778 TRACE("(%p) : Created Query %p\n", This
, object
);
782 /* example at http://www.fairyengine.com/articles/dxmultiviews.htm */
783 HRESULT WINAPI
IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice
* iface
, WINED3DPRESENT_PARAMETERS
* pPresentationParameters
, void** ppSwapChain
,
785 D3DCB_CREATERENDERTARGETFN D3DCB_CreateRenderTarget
,
786 D3DCB_CREATEDEPTHSTENCILSURFACEFN D3DCB_CreateDepthStencil
){
787 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
789 FIXME("(%p) : Stub\n",This
);
793 /** NOTE: These are ahead of the other getters and setters to save using a forward declartion **/
794 UINT WINAPI
IWineD3DDeviceImpl_GetNumberOfSwapChains(IWineD3DDevice
*iface
) {
795 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
797 FIXME("(%p) : Stub\n",This
);
801 HRESULT WINAPI
IWineD3DDeviceImpl_GetSwapChain(IWineD3DDevice
*iface
, UINT iSwapChain
, void** pSwapChain
) {
802 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
804 FIXME("(%p) : Stub\n",This
);
808 HRESULT WINAPI
IWineD3DDeviceImpl_Reset(IWineD3DDevice
* iface
, WINED3DPRESENT_PARAMETERS
* pPresentationParameters
){
809 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
811 FIXME("(%p) : Stub\n",This
);
819 /* TODO: Get ridd of thease and put the functions in the IWineD3DVertexDeclaration interface */
821 extern HRESULT
IWineD3DVertexDeclarationImpl_ParseDeclaration8(IWineD3DDeviceImpl
* This
, const DWORD
* pDecl
, IWineD3DVertexDeclarationImpl
* object
);
822 extern HRESULT
IWineD3DVertexDeclarationImpl_ParseDeclaration9(IWineD3DDeviceImpl
* This
, const D3DVERTEXELEMENT9
* pDecl
, IWineD3DVertexDeclarationImpl
* object
);
825 HRESULT WINAPI
IWineD3DDeviceImpl_CreateVertexDeclaration(IWineD3DDevice
* iface
, CONST VOID
* pDeclaration
, IWineD3DVertexDeclaration
** ppVertexDeclaration
, IUnknown
*parent
) {
826 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
827 IWineD3DVertexDeclarationImpl
*object
= NULL
;
830 TRACE("(%p) : directXVersion=%u, pFunction=%p, ppDecl=%p\n", This
, ((IWineD3DImpl
*)This
->wineD3D
)->dxVersion
, pDeclaration
, ppVertexDeclaration
);
831 D3DCREATEOBJECTINSTANCE(object
, VertexDeclaration
)
834 if (8 == ((IWineD3DImpl
*)This
->wineD3D
)->dxVersion
) {
836 hr
= IWineD3DVertexDeclarationImpl_ParseDeclaration8(This
, (const DWORD
*) pDeclaration
, object
);
838 hr
= IWineD3DVertexDeclarationImpl_ParseDeclaration9(This
, (const D3DVERTEXELEMENT9
*) pDeclaration
, object
);
846 HRESULT WINAPI
IWineD3DDeviceImpl_CreateVertexDeclaration8(IWineD3DDevice
* iface
, const DWORD
* pDeclaration
, IWineD3DVertexDeclaration
** ppVertexDeclaration
, IUnknown
*parent
){
847 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
848 IWineD3DVertexDeclarationImpl
*object
= NULL
; /* NOTE: impl allowed, this is a create */
850 /* TODO: replace impl usage with a call to Version*/
851 TRACE("(%p) : directXVersion=%u, pFunction=%p, ppDecl=%p\n", This
, ((IWineD3DImpl
*)This
->wineD3D
)->dxVersion
, pDeclaration
, ppVertexDeclaration
);
852 D3DCREATEOBJECTINSTANCE(object
, VertexDeclaration
)
854 /* TODO: get ridd of the impl usage, we should only be using interfaces */
855 hr
= IWineD3DVertexDeclarationImpl_ParseDeclaration8(This
, pDeclaration
, object
);
860 HRESULT WINAPI
IWineD3DDeviceImpl_CreateVertexDeclaration9(IWineD3DDevice
* iface
, const D3DVERTEXELEMENT9
* pDeclaration
, IWineD3DVertexDeclaration
** ppVertexDeclaration
, IUnknown
*parent
){
861 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
862 IWineD3DVertexDeclarationImpl
*object
= NULL
; /* NOTE: impl allowed, this is a create */
864 /* TODO: replace impl usage with a call to Version*/
865 TRACE("(%p) : directXVersion=%u, pFunction=%p, ppDecl=%p\n", This
, ((IWineD3DImpl
*)This
->wineD3D
)->dxVersion
, pDeclaration
, ppVertexDeclaration
);
866 D3DCREATEOBJECTINSTANCE(object
, VertexDeclaration
)
868 /* TODO: get ridd of the impl usage, we should only be using interfaces */
869 hr
= IWineD3DVertexDeclarationImpl_ParseDeclaration9(This
, pDeclaration
, object
);
875 /* http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/graphics/programmingguide/programmable/vertexshaders/vscreate.asp */
876 HRESULT WINAPI
IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice
* iface
, CONST DWORD
* pFunction
, IWineD3DVertexShader
** ppVertexShader
, IUnknown
*parent
){
877 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
878 IWineD3DVertexShaderImpl
*object
; /* NOTE: impl usage is ok, this is a create */
879 D3DCREATEOBJECTINSTANCE(object
, VertexShader
)
880 object
->function
= pFunction
;
881 FIXME("(%p) : STUB: Created Vertex shader %p\n", This
, ppVertexShader
);
886 HRESULT WINAPI
IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice
* iface
, CONST DWORD
* pFunction
, IWineD3DPixelShader
** ppPixelShader
, IUnknown
*parent
){
887 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
888 FIXME("(%p) : Stub\n", This
);
892 HRESULT WINAPI
IWineD3DDeviceImpl_GetDirect3D(IWineD3DDevice
* iface
, IWineD3D
** ppD3D
){
893 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
894 *ppD3D
= This
->wineD3D
;
895 TRACE("(%p) : wineD3D returning %p\n", This
, *ppD3D
);
896 IWineD3D_AddRef(*ppD3D
);
901 UINT WINAPI
IWineD3DDeviceImpl_GetAvailableTextureMem(IWineD3DDevice
*iface
) {
902 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
903 FIXME("Stub :(%p) returning 64Mib\n", This
);
911 HRESULT WINAPI
IWineD3DDeviceImpl_SetFVF(IWineD3DDevice
*iface
, DWORD fvf
) {
912 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
914 /* Update the current state block */
915 This
->updateStateBlock
->fvf
= fvf
;
916 This
->updateStateBlock
->changed
.fvf
= TRUE
;
917 This
->updateStateBlock
->set
.fvf
= TRUE
;
919 TRACE("(%p) : FVF Shader FVF set to %lx\n", This
, fvf
);
921 /* No difference if recording or not */
924 HRESULT WINAPI
IWineD3DDeviceImpl_GetFVF(IWineD3DDevice
*iface
, DWORD
*pfvf
) {
925 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
926 TRACE("(%p) : GetFVF returning %lx\n", This
, This
->stateBlock
->fvf
);
927 *pfvf
= This
->stateBlock
->fvf
;
932 * Get / Set Stream Source
934 HRESULT WINAPI
IWineD3DDeviceImpl_SetStreamSource(IWineD3DDevice
*iface
, UINT StreamNumber
,IWineD3DVertexBuffer
* pStreamData
, UINT OffsetInBytes
, UINT Stride
) {
935 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
936 IWineD3DVertexBuffer
*oldSrc
;
938 oldSrc
= This
->stateBlock
->stream_source
[StreamNumber
];
939 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This
, StreamNumber
, oldSrc
, pStreamData
, Stride
);
941 This
->updateStateBlock
->changed
.stream_source
[StreamNumber
] = TRUE
;
942 This
->updateStateBlock
->set
.stream_source
[StreamNumber
] = TRUE
;
943 This
->updateStateBlock
->stream_stride
[StreamNumber
] = Stride
;
944 This
->updateStateBlock
->stream_source
[StreamNumber
] = pStreamData
;
945 This
->updateStateBlock
->stream_offset
[StreamNumber
] = OffsetInBytes
;
947 /* Handle recording of state blocks */
948 if (This
->isRecordingState
) {
949 TRACE("Recording... not performing anything\n");
953 /* Not recording... */
954 if (oldSrc
!= NULL
) IWineD3DVertexBuffer_Release(oldSrc
);
955 if (pStreamData
!= NULL
) IWineD3DVertexBuffer_AddRef(pStreamData
);
960 HRESULT WINAPI
IWineD3DDeviceImpl_GetStreamSource(IWineD3DDevice
*iface
, UINT StreamNumber
,IWineD3DVertexBuffer
** pStream
, UINT
*pOffset
, UINT
* pStride
) {
961 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
963 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This
, StreamNumber
, This
->stateBlock
->stream_source
[StreamNumber
], This
->stateBlock
->stream_stride
[StreamNumber
]);
964 *pStream
= This
->stateBlock
->stream_source
[StreamNumber
];
965 *pStride
= This
->stateBlock
->stream_stride
[StreamNumber
];
966 *pOffset
= This
->stateBlock
->stream_offset
[StreamNumber
];
967 if (*pStream
!= NULL
) IWineD3DVertexBuffer_AddRef(*pStream
); /* We have created a new reference to the VB */
971 /*Should be quite easy, just an extension of vertexdata
973 http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c_Summer_04/directx/graphics/programmingguide/advancedtopics/DrawingMultipleInstances.asp
975 The divider is a bit odd though
977 VertexOffset = StartVertex / Divider * StreamStride +
978 VertexIndex / Divider * StreamStride + StreamOffset
981 HRESULT WINAPI
IWineD3DDeviceImpl_SetStreamSourceFreq(IWineD3DDevice
*iface
, UINT StreamNumber
, UINT Divider
){
982 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
984 FIXME("(%p) : stub\n", This
);
988 HRESULT WINAPI
IWineD3DDeviceImpl_GetStreamSourceFreq(IWineD3DDevice
*iface
, UINT StreamNumber
, UINT
* Divider
){
989 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
991 FIXME("(%p) : stub\n", This
);
997 * Get / Set & Multipy Transform
999 HRESULT WINAPI
IWineD3DDeviceImpl_SetTransform(IWineD3DDevice
*iface
, D3DTRANSFORMSTATETYPE d3dts
, CONST D3DMATRIX
* lpmatrix
) {
1000 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1002 /* Most of this routine, comments included copied from ddraw tree initially: */
1003 TRACE("(%p) : Transform State=%d\n", This
, d3dts
);
1005 /* Handle recording of state blocks */
1006 if (This
->isRecordingState
) {
1007 TRACE("Recording... not performing anything\n");
1008 This
->updateStateBlock
->changed
.transform
[d3dts
] = TRUE
;
1009 This
->updateStateBlock
->set
.transform
[d3dts
] = TRUE
;
1010 memcpy(&This
->updateStateBlock
->transforms
[d3dts
], lpmatrix
, sizeof(D3DMATRIX
));
1015 * If the new matrix is the same as the current one,
1016 * we cut off any further processing. this seems to be a reasonable
1017 * optimization because as was noticed, some apps (warcraft3 for example)
1018 * tend towards setting the same matrix repeatedly for some reason.
1020 * From here on we assume that the new matrix is different, wherever it matters.
1022 if (!memcmp(&This
->stateBlock
->transforms
[d3dts
].u
.m
[0][0], lpmatrix
, sizeof(D3DMATRIX
))) {
1023 TRACE("The app is setting the same matrix over again\n");
1026 conv_mat(lpmatrix
, &This
->stateBlock
->transforms
[d3dts
].u
.m
[0][0]);
1030 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
1031 where ViewMat = Camera space, WorldMat = world space.
1033 In OpenGL, camera and world space is combined into GL_MODELVIEW
1034 matrix. The Projection matrix stay projection matrix.
1037 /* Capture the times we can just ignore the change for now */
1038 if (d3dts
== D3DTS_WORLDMATRIX(0)) {
1039 This
->modelview_valid
= FALSE
;
1042 } else if (d3dts
== D3DTS_PROJECTION
) {
1043 This
->proj_valid
= FALSE
;
1046 } else if (d3dts
>= D3DTS_WORLDMATRIX(1) && d3dts
<= D3DTS_WORLDMATRIX(255)) {
1047 /* Indexed Vertex Blending Matrices 256 -> 511 */
1048 /* Use arb_vertex_blend or NV_VERTEX_WEIGHTING? */
1049 FIXME("D3DTS_WORLDMATRIX(1..255) not handled\n");
1053 /* Now we really are going to have to change a matrix */
1056 if (d3dts
>= D3DTS_TEXTURE0
&& d3dts
<= D3DTS_TEXTURE7
) { /* handle texture matrices */
1057 if (d3dts
< GL_LIMITS(textures
)) {
1058 int tex
= d3dts
- D3DTS_TEXTURE0
;
1059 GLACTIVETEXTURE(tex
);
1060 set_texture_matrix((float *)lpmatrix
,
1061 This
->updateStateBlock
->textureState
[tex
][D3DTSS_TEXTURETRANSFORMFLAGS
]);
1064 } else if (d3dts
== D3DTS_VIEW
) { /* handle the VIEW matrice */
1067 /* If we are changing the View matrix, reset the light and clipping planes to the new view
1068 * NOTE: We have to reset the positions even if the light/plane is not currently
1069 * enabled, since the call to enable it will not reset the position.
1070 * NOTE2: Apparently texture transforms do NOT need reapplying
1073 PLIGHTINFOEL
*lightChain
= NULL
;
1074 This
->modelview_valid
= FALSE
;
1075 This
->view_ident
= !memcmp(lpmatrix
, identity
, 16*sizeof(float));
1077 glMatrixMode(GL_MODELVIEW
);
1078 checkGLcall("glMatrixMode(GL_MODELVIEW)");
1080 glLoadMatrixf((float *)lpmatrix
);
1081 checkGLcall("glLoadMatrixf(...)");
1084 lightChain
= This
->stateBlock
->lights
;
1085 while (lightChain
&& lightChain
->glIndex
!= -1) {
1086 glLightfv(GL_LIGHT0
+ lightChain
->glIndex
, GL_POSITION
, lightChain
->lightPosn
);
1087 checkGLcall("glLightfv posn");
1088 glLightfv(GL_LIGHT0
+ lightChain
->glIndex
, GL_SPOT_DIRECTION
, lightChain
->lightDirn
);
1089 checkGLcall("glLightfv dirn");
1090 lightChain
= lightChain
->next
;
1093 /* Reset Clipping Planes if clipping is enabled */
1094 for (k
= 0; k
< GL_LIMITS(clipplanes
); k
++) {
1095 glClipPlane(GL_CLIP_PLANE0
+ k
, This
->stateBlock
->clipplane
[k
]);
1096 checkGLcall("glClipPlane");
1100 } else { /* What was requested!?? */
1101 WARN("invalid matrix specified: %i\n", d3dts
);
1104 /* Release lock, all done */
1109 HRESULT WINAPI
IWineD3DDeviceImpl_GetTransform(IWineD3DDevice
*iface
, D3DTRANSFORMSTATETYPE State
, D3DMATRIX
* pMatrix
) {
1110 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1111 TRACE("(%p) : for Transform State %d\n", This
, State
);
1112 memcpy(pMatrix
, &This
->stateBlock
->transforms
[State
], sizeof(D3DMATRIX
));
1116 HRESULT WINAPI
IWineD3DDeviceImpl_MultiplyTransform(IWineD3DDevice
*iface
, D3DTRANSFORMSTATETYPE State
, CONST D3DMATRIX
* pMatrix
) {
1117 D3DMATRIX
*mat
= NULL
;
1120 /* Note: Using 'updateStateBlock' rather than 'stateblock' in the code
1121 * below means it will be recorded in a state block change, but it
1122 * works regardless where it is recorded.
1123 * If this is found to be wrong, change to StateBlock.
1125 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1126 TRACE("(%p) : For state %u\n", This
, State
);
1128 if (State
< HIGHEST_TRANSFORMSTATE
)
1130 mat
= &This
->updateStateBlock
->transforms
[State
];
1132 FIXME("Unhandled transform state!!\n");
1135 /* Copied from ddraw code: */
1136 temp
.u
.s
._11
= (mat
->u
.s
._11
* pMatrix
->u
.s
._11
) + (mat
->u
.s
._21
* pMatrix
->u
.s
._12
) + (mat
->u
.s
._31
* pMatrix
->u
.s
._13
) + (mat
->u
.s
._41
* pMatrix
->u
.s
._14
);
1137 temp
.u
.s
._21
= (mat
->u
.s
._11
* pMatrix
->u
.s
._21
) + (mat
->u
.s
._21
* pMatrix
->u
.s
._22
) + (mat
->u
.s
._31
* pMatrix
->u
.s
._23
) + (mat
->u
.s
._41
* pMatrix
->u
.s
._24
);
1138 temp
.u
.s
._31
= (mat
->u
.s
._11
* pMatrix
->u
.s
._31
) + (mat
->u
.s
._21
* pMatrix
->u
.s
._32
) + (mat
->u
.s
._31
* pMatrix
->u
.s
._33
) + (mat
->u
.s
._41
* pMatrix
->u
.s
._34
);
1139 temp
.u
.s
._41
= (mat
->u
.s
._11
* pMatrix
->u
.s
._41
) + (mat
->u
.s
._21
* pMatrix
->u
.s
._42
) + (mat
->u
.s
._31
* pMatrix
->u
.s
._43
) + (mat
->u
.s
._41
* pMatrix
->u
.s
._44
);
1141 temp
.u
.s
._12
= (mat
->u
.s
._12
* pMatrix
->u
.s
._11
) + (mat
->u
.s
._22
* pMatrix
->u
.s
._12
) + (mat
->u
.s
._32
* pMatrix
->u
.s
._13
) + (mat
->u
.s
._42
* pMatrix
->u
.s
._14
);
1142 temp
.u
.s
._22
= (mat
->u
.s
._12
* pMatrix
->u
.s
._21
) + (mat
->u
.s
._22
* pMatrix
->u
.s
._22
) + (mat
->u
.s
._32
* pMatrix
->u
.s
._23
) + (mat
->u
.s
._42
* pMatrix
->u
.s
._24
);
1143 temp
.u
.s
._32
= (mat
->u
.s
._12
* pMatrix
->u
.s
._31
) + (mat
->u
.s
._22
* pMatrix
->u
.s
._32
) + (mat
->u
.s
._32
* pMatrix
->u
.s
._33
) + (mat
->u
.s
._42
* pMatrix
->u
.s
._34
);
1144 temp
.u
.s
._42
= (mat
->u
.s
._12
* pMatrix
->u
.s
._41
) + (mat
->u
.s
._22
* pMatrix
->u
.s
._42
) + (mat
->u
.s
._32
* pMatrix
->u
.s
._43
) + (mat
->u
.s
._42
* pMatrix
->u
.s
._44
);
1146 temp
.u
.s
._13
= (mat
->u
.s
._13
* pMatrix
->u
.s
._11
) + (mat
->u
.s
._23
* pMatrix
->u
.s
._12
) + (mat
->u
.s
._33
* pMatrix
->u
.s
._13
) + (mat
->u
.s
._43
* pMatrix
->u
.s
._14
);
1147 temp
.u
.s
._23
= (mat
->u
.s
._13
* pMatrix
->u
.s
._21
) + (mat
->u
.s
._23
* pMatrix
->u
.s
._22
) + (mat
->u
.s
._33
* pMatrix
->u
.s
._23
) + (mat
->u
.s
._43
* pMatrix
->u
.s
._24
);
1148 temp
.u
.s
._33
= (mat
->u
.s
._13
* pMatrix
->u
.s
._31
) + (mat
->u
.s
._23
* pMatrix
->u
.s
._32
) + (mat
->u
.s
._33
* pMatrix
->u
.s
._33
) + (mat
->u
.s
._43
* pMatrix
->u
.s
._34
);
1149 temp
.u
.s
._43
= (mat
->u
.s
._13
* pMatrix
->u
.s
._41
) + (mat
->u
.s
._23
* pMatrix
->u
.s
._42
) + (mat
->u
.s
._33
* pMatrix
->u
.s
._43
) + (mat
->u
.s
._43
* pMatrix
->u
.s
._44
);
1151 temp
.u
.s
._14
= (mat
->u
.s
._14
* pMatrix
->u
.s
._11
) + (mat
->u
.s
._24
* pMatrix
->u
.s
._12
) + (mat
->u
.s
._34
* pMatrix
->u
.s
._13
) + (mat
->u
.s
._44
* pMatrix
->u
.s
._14
);
1152 temp
.u
.s
._24
= (mat
->u
.s
._14
* pMatrix
->u
.s
._21
) + (mat
->u
.s
._24
* pMatrix
->u
.s
._22
) + (mat
->u
.s
._34
* pMatrix
->u
.s
._23
) + (mat
->u
.s
._44
* pMatrix
->u
.s
._24
);
1153 temp
.u
.s
._34
= (mat
->u
.s
._14
* pMatrix
->u
.s
._31
) + (mat
->u
.s
._24
* pMatrix
->u
.s
._32
) + (mat
->u
.s
._34
* pMatrix
->u
.s
._33
) + (mat
->u
.s
._44
* pMatrix
->u
.s
._34
);
1154 temp
.u
.s
._44
= (mat
->u
.s
._14
* pMatrix
->u
.s
._41
) + (mat
->u
.s
._24
* pMatrix
->u
.s
._42
) + (mat
->u
.s
._34
* pMatrix
->u
.s
._43
) + (mat
->u
.s
._44
* pMatrix
->u
.s
._44
);
1156 /* Apply change via set transform - will reapply to eg. lights this way */
1157 IWineD3DDeviceImpl_SetTransform(iface
, State
, &temp
);
1163 * WARNING: This code relies on the fact that D3DLIGHT8 == D3DLIGHT9
1165 /* Note lights are real special cases. Although the device caps state only eg. 8 are supported,
1166 you can reference any indexes you want as long as that number max are enabled at any
1167 one point in time! Therefore since the indexes can be anything, we need a linked list of them.
1168 However, this causes stateblock problems. When capturing the state block, I duplicate the list,
1169 but when recording, just build a chain pretty much of commands to be replayed. */
1171 HRESULT WINAPI
IWineD3DDeviceImpl_SetLight(IWineD3DDevice
*iface
, DWORD Index
, CONST WINED3DLIGHT
* pLight
) {
1173 PLIGHTINFOEL
*object
, *temp
;
1175 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1176 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This
, Index
, pLight
);
1178 /* If recording state block, just add to end of lights chain */
1179 if (This
->isRecordingState
) {
1180 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(PLIGHTINFOEL
));
1181 if (NULL
== object
) {
1182 return D3DERR_OUTOFVIDEOMEMORY
;
1184 memcpy(&object
->OriginalParms
, pLight
, sizeof(D3DLIGHT9
));
1185 object
->OriginalIndex
= Index
;
1186 object
->glIndex
= -1;
1187 object
->changed
= TRUE
;
1189 /* Add to the END of the chain of lights changes to be replayed */
1190 if (This
->updateStateBlock
->lights
== NULL
) {
1191 This
->updateStateBlock
->lights
= object
;
1193 temp
= This
->updateStateBlock
->lights
;
1194 while (temp
->next
!= NULL
) temp
=temp
->next
;
1195 temp
->next
= object
;
1197 TRACE("Recording... not performing anything more\n");
1201 /* Ok, not recording any longer so do real work */
1202 object
= This
->stateBlock
->lights
;
1203 while (object
!= NULL
&& object
->OriginalIndex
!= Index
) object
= object
->next
;
1205 /* If we didn't find it in the list of lights, time to add it */
1206 if (object
== NULL
) {
1207 PLIGHTINFOEL
*insertAt
,*prevPos
;
1209 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(PLIGHTINFOEL
));
1210 if (NULL
== object
) {
1211 return D3DERR_OUTOFVIDEOMEMORY
;
1213 object
->OriginalIndex
= Index
;
1214 object
->glIndex
= -1;
1216 /* Add it to the front of list with the idea that lights will be changed as needed
1217 BUT after any lights currently assigned GL indexes */
1218 insertAt
= This
->stateBlock
->lights
;
1220 while (insertAt
!= NULL
&& insertAt
->glIndex
!= -1) {
1222 insertAt
= insertAt
->next
;
1225 if (insertAt
== NULL
&& prevPos
== NULL
) { /* Start of list */
1226 This
->stateBlock
->lights
= object
;
1227 } else if (insertAt
== NULL
) { /* End of list */
1228 prevPos
->next
= object
;
1229 object
->prev
= prevPos
;
1230 } else { /* Middle of chain */
1231 if (prevPos
== NULL
) {
1232 This
->stateBlock
->lights
= object
;
1234 prevPos
->next
= object
;
1236 object
->prev
= prevPos
;
1237 object
->next
= insertAt
;
1238 insertAt
->prev
= object
;
1242 /* Initialze the object */
1243 TRACE("Light %ld setting to type %d, Diffuse(%f,%f,%f,%f), Specular(%f,%f,%f,%f), Ambient(%f,%f,%f,%f)\n", Index
, pLight
->Type
,
1244 pLight
->Diffuse
.r
, pLight
->Diffuse
.g
, pLight
->Diffuse
.b
, pLight
->Diffuse
.a
,
1245 pLight
->Specular
.r
, pLight
->Specular
.g
, pLight
->Specular
.b
, pLight
->Specular
.a
,
1246 pLight
->Ambient
.r
, pLight
->Ambient
.g
, pLight
->Ambient
.b
, pLight
->Ambient
.a
);
1247 TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight
->Position
.x
, pLight
->Position
.y
, pLight
->Position
.z
,
1248 pLight
->Direction
.x
, pLight
->Direction
.y
, pLight
->Direction
.z
);
1249 TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight
->Range
, pLight
->Falloff
, pLight
->Theta
, pLight
->Phi
);
1251 /* Save away the information */
1252 memcpy(&object
->OriginalParms
, pLight
, sizeof(D3DLIGHT9
));
1254 switch (pLight
->Type
) {
1255 case D3DLIGHT_POINT
:
1257 object
->lightPosn
[0] = pLight
->Position
.x
;
1258 object
->lightPosn
[1] = pLight
->Position
.y
;
1259 object
->lightPosn
[2] = pLight
->Position
.z
;
1260 object
->lightPosn
[3] = 1.0f
;
1261 object
->cutoff
= 180.0f
;
1265 case D3DLIGHT_DIRECTIONAL
:
1267 object
->lightPosn
[0] = -pLight
->Direction
.x
;
1268 object
->lightPosn
[1] = -pLight
->Direction
.y
;
1269 object
->lightPosn
[2] = -pLight
->Direction
.z
;
1270 object
->lightPosn
[3] = 0.0;
1271 object
->exponent
= 0.0f
;
1272 object
->cutoff
= 180.0f
;
1277 object
->lightPosn
[0] = pLight
->Position
.x
;
1278 object
->lightPosn
[1] = pLight
->Position
.y
;
1279 object
->lightPosn
[2] = pLight
->Position
.z
;
1280 object
->lightPosn
[3] = 1.0;
1283 object
->lightDirn
[0] = pLight
->Direction
.x
;
1284 object
->lightDirn
[1] = pLight
->Direction
.y
;
1285 object
->lightDirn
[2] = pLight
->Direction
.z
;
1286 object
->lightDirn
[3] = 1.0;
1289 * opengl-ish and d3d-ish spot lights use too different models for the
1290 * light "intensity" as a function of the angle towards the main light direction,
1291 * so we only can approximate very roughly.
1292 * however spot lights are rather rarely used in games (if ever used at all).
1293 * furthermore if still used, probably nobody pays attention to such details.
1295 if (pLight
->Falloff
== 0) {
1298 rho
= pLight
->Theta
+ (pLight
->Phi
- pLight
->Theta
)/(2*pLight
->Falloff
);
1300 if (rho
< 0.0001) rho
= 0.0001f
;
1301 object
->exponent
= -0.3/log(cos(rho
/2));
1302 object
->cutoff
= pLight
->Phi
*90/M_PI
;
1308 FIXME("Unrecognized light type %d\n", pLight
->Type
);
1311 /* Update the live definitions if the light is currently assigned a glIndex */
1312 if (object
->glIndex
!= -1) {
1313 setup_light(iface
, object
->glIndex
, object
);
1318 HRESULT WINAPI
IWineD3DDeviceImpl_GetLight(IWineD3DDevice
*iface
, DWORD Index
, WINED3DLIGHT
* pLight
) {
1319 PLIGHTINFOEL
*lightInfo
= NULL
;
1320 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1321 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This
, Index
, pLight
);
1323 /* Locate the light in the live lights */
1324 lightInfo
= This
->stateBlock
->lights
;
1325 while (lightInfo
!= NULL
&& lightInfo
->OriginalIndex
!= Index
) lightInfo
= lightInfo
->next
;
1327 if (lightInfo
== NULL
) {
1328 TRACE("Light information requested but light not defined\n");
1329 return D3DERR_INVALIDCALL
;
1332 memcpy(pLight
, &lightInfo
->OriginalParms
, sizeof(D3DLIGHT9
));
1337 * Get / Set Light Enable
1338 * (Note for consistency, renamed d3dx function by adding the 'set' prefix)
1340 HRESULT WINAPI
IWineD3DDeviceImpl_SetLightEnable(IWineD3DDevice
*iface
, DWORD Index
, BOOL Enable
) {
1341 PLIGHTINFOEL
*lightInfo
= NULL
;
1342 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1343 TRACE("(%p) : Idx(%ld), enable? %d\n", This
, Index
, Enable
);
1345 /* If recording state block, just add to end of lights chain with changedEnable set to true */
1346 if (This
->isRecordingState
) {
1347 lightInfo
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(PLIGHTINFOEL
));
1348 if (NULL
== lightInfo
) {
1349 return D3DERR_OUTOFVIDEOMEMORY
;
1351 lightInfo
->OriginalIndex
= Index
;
1352 lightInfo
->glIndex
= -1;
1353 lightInfo
->enabledChanged
= TRUE
;
1355 /* Add to the END of the chain of lights changes to be replayed */
1356 if (This
->updateStateBlock
->lights
== NULL
) {
1357 This
->updateStateBlock
->lights
= lightInfo
;
1359 PLIGHTINFOEL
*temp
= This
->updateStateBlock
->lights
;
1360 while (temp
->next
!= NULL
) temp
=temp
->next
;
1361 temp
->next
= lightInfo
;
1363 TRACE("Recording... not performing anything more\n");
1367 /* Not recording... So, locate the light in the live lights */
1368 lightInfo
= This
->stateBlock
->lights
;
1369 while (lightInfo
!= NULL
&& lightInfo
->OriginalIndex
!= Index
) lightInfo
= lightInfo
->next
;
1371 /* Special case - enabling an undefined light creates one with a strict set of parms! */
1372 if (lightInfo
== NULL
) {
1373 D3DLIGHT9 lightParms
;
1374 /* Warning - untested code :-) Prob safe to change fixme to a trace but
1375 wait until someone confirms it seems to work! */
1376 TRACE("Light enabled requested but light not defined, so defining one!\n");
1377 lightParms
.Type
= D3DLIGHT_DIRECTIONAL
;
1378 lightParms
.Diffuse
.r
= 1.0;
1379 lightParms
.Diffuse
.g
= 1.0;
1380 lightParms
.Diffuse
.b
= 1.0;
1381 lightParms
.Diffuse
.a
= 0.0;
1382 lightParms
.Specular
.r
= 0.0;
1383 lightParms
.Specular
.g
= 0.0;
1384 lightParms
.Specular
.b
= 0.0;
1385 lightParms
.Specular
.a
= 0.0;
1386 lightParms
.Ambient
.r
= 0.0;
1387 lightParms
.Ambient
.g
= 0.0;
1388 lightParms
.Ambient
.b
= 0.0;
1389 lightParms
.Ambient
.a
= 0.0;
1390 lightParms
.Position
.x
= 0.0;
1391 lightParms
.Position
.y
= 0.0;
1392 lightParms
.Position
.z
= 0.0;
1393 lightParms
.Direction
.x
= 0.0;
1394 lightParms
.Direction
.y
= 0.0;
1395 lightParms
.Direction
.z
= 1.0;
1396 lightParms
.Range
= 0.0;
1397 lightParms
.Falloff
= 0.0;
1398 lightParms
.Attenuation0
= 0.0;
1399 lightParms
.Attenuation1
= 0.0;
1400 lightParms
.Attenuation2
= 0.0;
1401 lightParms
.Theta
= 0.0;
1402 lightParms
.Phi
= 0.0;
1403 IWineD3DDeviceImpl_SetLight(iface
, Index
, &lightParms
);
1405 /* Search for it again! Should be fairly quick as near head of list */
1406 lightInfo
= This
->stateBlock
->lights
;
1407 while (lightInfo
!= NULL
&& lightInfo
->OriginalIndex
!= Index
) lightInfo
= lightInfo
->next
;
1408 if (lightInfo
== NULL
) {
1409 FIXME("Adding default lights has failed dismally\n");
1410 return D3DERR_INVALIDCALL
;
1414 /* OK, we now have a light... */
1415 if (Enable
== FALSE
) {
1417 /* If we are disabling it, check it was enabled, and
1418 still only do something if it has assigned a glIndex (which it should have!) */
1419 if ((lightInfo
->lightEnabled
) && (lightInfo
->glIndex
!= -1)) {
1420 TRACE("Disabling light set up at gl idx %ld\n", lightInfo
->glIndex
);
1422 glDisable(GL_LIGHT0
+ lightInfo
->glIndex
);
1423 checkGLcall("glDisable GL_LIGHT0+Index");
1426 TRACE("Nothing to do as light was not enabled\n");
1428 lightInfo
->lightEnabled
= FALSE
;
1431 /* We are enabling it. If it is enabled, it's really simple */
1432 if (lightInfo
->lightEnabled
) {
1434 TRACE("Nothing to do as light was enabled\n");
1436 /* If it already has a glIndex, it's still simple */
1437 } else if (lightInfo
->glIndex
!= -1) {
1438 TRACE("Reusing light as already set up at gl idx %ld\n", lightInfo
->glIndex
);
1439 lightInfo
->lightEnabled
= TRUE
;
1441 glEnable(GL_LIGHT0
+ lightInfo
->glIndex
);
1442 checkGLcall("glEnable GL_LIGHT0+Index already setup");
1445 /* Otherwise got to find space - lights are ordered gl indexes first */
1447 PLIGHTINFOEL
*bsf
= NULL
;
1448 PLIGHTINFOEL
*pos
= This
->stateBlock
->lights
;
1449 PLIGHTINFOEL
*prev
= NULL
;
1453 /* Try to minimize changes as much as possible */
1454 while (pos
!= NULL
&& pos
->glIndex
!= -1 && Index
< This
->maxConcurrentLights
) {
1456 /* Try to remember which index can be replaced if necessary */
1457 if (bsf
==NULL
&& pos
->lightEnabled
== FALSE
) {
1458 /* Found a light we can replace, save as best replacement */
1462 /* Step to next space */
1468 /* If we have too many active lights, fail the call */
1469 if ((Index
== This
->maxConcurrentLights
) && (bsf
== NULL
)) {
1470 FIXME("Program requests too many concurrent lights\n");
1471 return D3DERR_INVALIDCALL
;
1473 /* If we have allocated all lights, but not all are enabled,
1474 reuse one which is not enabled */
1475 } else if (Index
== This
->maxConcurrentLights
) {
1476 /* use bsf - Simply swap the new light and the BSF one */
1477 PLIGHTINFOEL
*bsfNext
= bsf
->next
;
1478 PLIGHTINFOEL
*bsfPrev
= bsf
->prev
;
1481 if (lightInfo
->next
!= NULL
) lightInfo
->next
->prev
= bsf
;
1482 if (bsf
->prev
!= NULL
) {
1483 bsf
->prev
->next
= lightInfo
;
1485 This
->stateBlock
->lights
= lightInfo
;
1488 /* If not side by side, lots of chains to update */
1489 if (bsf
->next
!= lightInfo
) {
1490 lightInfo
->prev
->next
= bsf
;
1491 bsf
->next
->prev
= lightInfo
;
1492 bsf
->next
= lightInfo
->next
;
1493 bsf
->prev
= lightInfo
->prev
;
1494 lightInfo
->next
= bsfNext
;
1495 lightInfo
->prev
= bsfPrev
;
1499 bsf
->prev
= lightInfo
;
1500 bsf
->next
= lightInfo
->next
;
1501 lightInfo
->next
= bsf
;
1502 lightInfo
->prev
= bsfPrev
;
1507 glIndex
= bsf
->glIndex
;
1509 lightInfo
->glIndex
= glIndex
;
1510 lightInfo
->lightEnabled
= TRUE
;
1512 /* Finally set up the light in gl itself */
1513 TRACE("Replacing light which was set up at gl idx %ld\n", lightInfo
->glIndex
);
1515 setup_light(iface
, glIndex
, lightInfo
);
1516 glEnable(GL_LIGHT0
+ glIndex
);
1517 checkGLcall("glEnable GL_LIGHT0 new setup");
1520 /* If we reached the end of the allocated lights, with space in the
1521 gl lights, setup a new light */
1522 } else if (pos
->glIndex
== -1) {
1524 /* We reached the end of the allocated gl lights, so already
1525 know the index of the next one! */
1527 lightInfo
->glIndex
= glIndex
;
1528 lightInfo
->lightEnabled
= TRUE
;
1530 /* In an ideal world, it's already in the right place */
1531 if (lightInfo
->prev
== NULL
|| lightInfo
->prev
->glIndex
!=-1) {
1532 /* No need to move it */
1534 /* Remove this light from the list */
1535 lightInfo
->prev
->next
= lightInfo
->next
;
1536 if (lightInfo
->next
!= NULL
) {
1537 lightInfo
->next
->prev
= lightInfo
->prev
;
1540 /* Add in at appropriate place (inbetween prev and pos) */
1541 lightInfo
->prev
= prev
;
1542 lightInfo
->next
= pos
;
1544 This
->stateBlock
->lights
= lightInfo
;
1546 prev
->next
= lightInfo
;
1549 pos
->prev
= lightInfo
;
1553 /* Finally set up the light in gl itself */
1554 TRACE("Defining new light at gl idx %ld\n", lightInfo
->glIndex
);
1556 setup_light(iface
, glIndex
, lightInfo
);
1557 glEnable(GL_LIGHT0
+ glIndex
);
1558 checkGLcall("glEnable GL_LIGHT0 new setup");
1567 HRESULT WINAPI
IWineD3DDeviceImpl_GetLightEnable(IWineD3DDevice
*iface
, DWORD Index
,BOOL
* pEnable
) {
1569 PLIGHTINFOEL
*lightInfo
= NULL
;
1570 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1571 TRACE("(%p) : for idx(%ld)\n", This
, Index
);
1573 /* Locate the light in the live lights */
1574 lightInfo
= This
->stateBlock
->lights
;
1575 while (lightInfo
!= NULL
&& lightInfo
->OriginalIndex
!= Index
) lightInfo
= lightInfo
->next
;
1577 if (lightInfo
== NULL
) {
1578 TRACE("Light enabled state requested but light not defined\n");
1579 return D3DERR_INVALIDCALL
;
1581 *pEnable
= lightInfo
->lightEnabled
;
1586 * Get / Set Clip Planes
1588 HRESULT WINAPI
IWineD3DDeviceImpl_SetClipPlane(IWineD3DDevice
*iface
, DWORD Index
, CONST
float *pPlane
) {
1589 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1590 TRACE("(%p) : for idx %ld, %p\n", This
, Index
, pPlane
);
1592 /* Validate Index */
1593 if (Index
>= GL_LIMITS(clipplanes
)) {
1594 TRACE("Application has requested clipplane this device doesn't support\n");
1595 return D3DERR_INVALIDCALL
;
1598 This
->updateStateBlock
->changed
.clipplane
[Index
] = TRUE
;
1599 This
->updateStateBlock
->set
.clipplane
[Index
] = TRUE
;
1600 This
->updateStateBlock
->clipplane
[Index
][0] = pPlane
[0];
1601 This
->updateStateBlock
->clipplane
[Index
][1] = pPlane
[1];
1602 This
->updateStateBlock
->clipplane
[Index
][2] = pPlane
[2];
1603 This
->updateStateBlock
->clipplane
[Index
][3] = pPlane
[3];
1605 /* Handle recording of state blocks */
1606 if (This
->isRecordingState
) {
1607 TRACE("Recording... not performing anything\n");
1615 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
1616 glMatrixMode(GL_MODELVIEW
);
1618 glLoadMatrixf((float *) &This
->stateBlock
->transforms
[D3DTS_VIEW
].u
.m
[0][0]);
1620 TRACE("Clipplane [%f,%f,%f,%f]\n",
1621 This
->updateStateBlock
->clipplane
[Index
][0],
1622 This
->updateStateBlock
->clipplane
[Index
][1],
1623 This
->updateStateBlock
->clipplane
[Index
][2],
1624 This
->updateStateBlock
->clipplane
[Index
][3]);
1625 glClipPlane(GL_CLIP_PLANE0
+ Index
, This
->updateStateBlock
->clipplane
[Index
]);
1626 checkGLcall("glClipPlane");
1634 HRESULT WINAPI
IWineD3DDeviceImpl_GetClipPlane(IWineD3DDevice
*iface
, DWORD Index
, float *pPlane
) {
1635 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1636 TRACE("(%p) : for idx %ld\n", This
, Index
);
1638 /* Validate Index */
1639 if (Index
>= GL_LIMITS(clipplanes
)) {
1640 TRACE("Application has requested clipplane this device doesn't support\n");
1641 return D3DERR_INVALIDCALL
;
1644 pPlane
[0] = This
->stateBlock
->clipplane
[Index
][0];
1645 pPlane
[1] = This
->stateBlock
->clipplane
[Index
][1];
1646 pPlane
[2] = This
->stateBlock
->clipplane
[Index
][2];
1647 pPlane
[3] = This
->stateBlock
->clipplane
[Index
][3];
1652 * Get / Set Clip Plane Status
1653 * WARNING: This code relies on the fact that D3DCLIPSTATUS8 == D3DCLIPSTATUS9
1655 HRESULT WINAPI
IWineD3DDeviceImpl_SetClipStatus(IWineD3DDevice
*iface
, CONST WINED3DCLIPSTATUS
* pClipStatus
) {
1656 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1657 FIXME("(%p) : stub\n", This
);
1658 if (NULL
== pClipStatus
) {
1659 return D3DERR_INVALIDCALL
;
1661 This
->updateStateBlock
->clip_status
.ClipUnion
= pClipStatus
->ClipUnion
;
1662 This
->updateStateBlock
->clip_status
.ClipIntersection
= pClipStatus
->ClipIntersection
;
1666 HRESULT WINAPI
IWineD3DDeviceImpl_GetClipStatus(IWineD3DDevice
*iface
, WINED3DCLIPSTATUS
* pClipStatus
) {
1667 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1668 FIXME("(%p) : stub\n", This
);
1669 if (NULL
== pClipStatus
) {
1670 return D3DERR_INVALIDCALL
;
1672 pClipStatus
->ClipUnion
= This
->updateStateBlock
->clip_status
.ClipUnion
;
1673 pClipStatus
->ClipIntersection
= This
->updateStateBlock
->clip_status
.ClipIntersection
;
1678 * Get / Set Material
1679 * WARNING: This code relies on the fact that D3DMATERIAL8 == D3DMATERIAL9
1681 HRESULT WINAPI
IWineD3DDeviceImpl_SetMaterial(IWineD3DDevice
*iface
, CONST WINED3DMATERIAL
* pMaterial
) {
1682 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1684 This
->updateStateBlock
->changed
.material
= TRUE
;
1685 This
->updateStateBlock
->set
.material
= TRUE
;
1686 memcpy(&This
->updateStateBlock
->material
, pMaterial
, sizeof(WINED3DMATERIAL
));
1688 /* Handle recording of state blocks */
1689 if (This
->isRecordingState
) {
1690 TRACE("Recording... not performing anything\n");
1695 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This
, pMaterial
->Diffuse
.r
, pMaterial
->Diffuse
.g
, pMaterial
->Diffuse
.b
, pMaterial
->Diffuse
.a
);
1696 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This
, pMaterial
->Ambient
.r
, pMaterial
->Ambient
.g
, pMaterial
->Ambient
.b
, pMaterial
->Ambient
.a
);
1697 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This
, pMaterial
->Specular
.r
, pMaterial
->Specular
.g
, pMaterial
->Specular
.b
, pMaterial
->Specular
.a
);
1698 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This
, pMaterial
->Emissive
.r
, pMaterial
->Emissive
.g
, pMaterial
->Emissive
.b
, pMaterial
->Emissive
.a
);
1699 TRACE("(%p) : Power (%f)\n", This
, pMaterial
->Power
);
1701 glMaterialfv(GL_FRONT_AND_BACK
, GL_AMBIENT
, (float*) &This
->updateStateBlock
->material
.Ambient
);
1702 checkGLcall("glMaterialfv");
1703 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, (float*) &This
->updateStateBlock
->material
.Diffuse
);
1704 checkGLcall("glMaterialfv");
1706 /* Only change material color if specular is enabled, otherwise it is set to black */
1707 if (This
->stateBlock
->renderState
[WINED3DRS_SPECULARENABLE
]) {
1708 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, (float*) &This
->updateStateBlock
->material
.Specular
);
1709 checkGLcall("glMaterialfv");
1711 float black
[4] = {0.0f
, 0.0f
, 0.0f
, 0.0f
};
1712 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, &black
[0]);
1713 checkGLcall("glMaterialfv");
1715 glMaterialfv(GL_FRONT_AND_BACK
, GL_EMISSION
, (float*) &This
->updateStateBlock
->material
.Emissive
);
1716 checkGLcall("glMaterialfv");
1717 glMaterialf(GL_FRONT_AND_BACK
, GL_SHININESS
, This
->updateStateBlock
->material
.Power
);
1718 checkGLcall("glMaterialf");
1724 HRESULT WINAPI
IWineD3DDeviceImpl_GetMaterial(IWineD3DDevice
*iface
, WINED3DMATERIAL
* pMaterial
) {
1725 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1726 memcpy(pMaterial
, &This
->updateStateBlock
->material
, sizeof (WINED3DMATERIAL
));
1727 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This
, pMaterial
->Diffuse
.r
, pMaterial
->Diffuse
.g
, pMaterial
->Diffuse
.b
, pMaterial
->Diffuse
.a
);
1728 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This
, pMaterial
->Ambient
.r
, pMaterial
->Ambient
.g
, pMaterial
->Ambient
.b
, pMaterial
->Ambient
.a
);
1729 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This
, pMaterial
->Specular
.r
, pMaterial
->Specular
.g
, pMaterial
->Specular
.b
, pMaterial
->Specular
.a
);
1730 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This
, pMaterial
->Emissive
.r
, pMaterial
->Emissive
.g
, pMaterial
->Emissive
.b
, pMaterial
->Emissive
.a
);
1731 TRACE("(%p) : Power (%f)\n", This
, pMaterial
->Power
);
1738 HRESULT WINAPI
IWineD3DDeviceImpl_SetIndices(IWineD3DDevice
*iface
, IWineD3DIndexBuffer
* pIndexData
,
1739 UINT BaseVertexIndex
) {
1740 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1741 IWineD3DIndexBuffer
*oldIdxs
;
1743 TRACE("(%p) : Setting to %p, base %d\n", This
, pIndexData
, BaseVertexIndex
);
1744 oldIdxs
= This
->updateStateBlock
->pIndexData
;
1746 This
->updateStateBlock
->changed
.indices
= TRUE
;
1747 This
->updateStateBlock
->set
.indices
= TRUE
;
1748 This
->updateStateBlock
->pIndexData
= pIndexData
;
1749 This
->updateStateBlock
->baseVertexIndex
= BaseVertexIndex
;
1751 /* Handle recording of state blocks */
1752 if (This
->isRecordingState
) {
1753 TRACE("Recording... not performing anything\n");
1757 if (oldIdxs
) IWineD3DIndexBuffer_Release(oldIdxs
);
1758 if (pIndexData
) IWineD3DIndexBuffer_AddRef(This
->stateBlock
->pIndexData
);
1762 HRESULT WINAPI
IWineD3DDeviceImpl_GetIndices(IWineD3DDevice
*iface
, IWineD3DIndexBuffer
** ppIndexData
, UINT
* pBaseVertexIndex
) {
1763 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1765 *ppIndexData
= This
->stateBlock
->pIndexData
;
1767 /* up ref count on ppindexdata */
1768 if (*ppIndexData
) IWineD3DIndexBuffer_AddRef(*ppIndexData
);
1769 *pBaseVertexIndex
= This
->stateBlock
->baseVertexIndex
;
1775 * Get / Set Viewports
1777 HRESULT WINAPI
IWineD3DDeviceImpl_SetViewport(IWineD3DDevice
*iface
, CONST WINED3DVIEWPORT
* pViewport
) {
1778 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1780 TRACE("(%p)\n", This
);
1781 This
->updateStateBlock
->changed
.viewport
= TRUE
;
1782 This
->updateStateBlock
->set
.viewport
= TRUE
;
1783 memcpy(&This
->updateStateBlock
->viewport
, pViewport
, sizeof(WINED3DVIEWPORT
));
1785 /* Handle recording of state blocks */
1786 if (This
->isRecordingState
) {
1787 TRACE("Recording... not performing anything\n");
1793 TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This
,
1794 pViewport
->X
, pViewport
->Y
, pViewport
->Width
, pViewport
->Height
, pViewport
->MinZ
, pViewport
->MaxZ
);
1796 glDepthRange(pViewport
->MinZ
, pViewport
->MaxZ
);
1797 checkGLcall("glDepthRange");
1798 /* Note: GL requires lower left, DirectX supplies upper left */
1799 /* TODO: replace usage of renderTarget with context management */
1800 glViewport(pViewport
->X
, (((IWineD3DSurfaceImpl
*)This
->renderTarget
)->currentDesc
.Height
- (pViewport
->Y
+ pViewport
->Height
)),
1801 pViewport
->Width
, pViewport
->Height
);
1802 checkGLcall("glViewport");
1810 HRESULT WINAPI
IWineD3DDeviceImpl_GetViewport(IWineD3DDevice
*iface
, WINED3DVIEWPORT
* pViewport
) {
1811 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1812 TRACE("(%p)\n", This
);
1813 memcpy(pViewport
, &This
->stateBlock
->viewport
, sizeof(WINED3DVIEWPORT
));
1818 * Get / Set Render States
1819 * TODO: Verify against dx9 definitions
1821 HRESULT WINAPI
IWineD3DDeviceImpl_SetRenderState(IWineD3DDevice
*iface
, D3DRENDERSTATETYPE State
, DWORD Value
) {
1823 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
1824 DWORD OldValue
= This
->stateBlock
->renderState
[State
];
1826 /* Simple way of referring to either a DWORD or a 4 byte float */
1832 TRACE("(%p)->state = %s(%d), value = %ld\n", This
, debug_d3drenderstate(State
), State
, Value
);
1833 This
->updateStateBlock
->changed
.renderState
[State
] = TRUE
;
1834 This
->updateStateBlock
->set
.renderState
[State
] = TRUE
;
1835 This
->updateStateBlock
->renderState
[State
] = Value
;
1837 /* Handle recording of state blocks */
1838 if (This
->isRecordingState
) {
1839 TRACE("Recording... not performing anything\n");
1846 case WINED3DRS_FILLMODE
:
1847 switch ((D3DFILLMODE
) Value
) {
1848 case D3DFILL_POINT
: glPolygonMode(GL_FRONT_AND_BACK
, GL_POINT
); break;
1849 case D3DFILL_WIREFRAME
: glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
); break;
1850 case D3DFILL_SOLID
: glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
); break;
1852 FIXME("Unrecognized WINED3DRS_FILLMODE value %ld\n", Value
);
1854 checkGLcall("glPolygonMode (fillmode)");
1857 case WINED3DRS_LIGHTING
:
1859 glEnable(GL_LIGHTING
);
1860 checkGLcall("glEnable GL_LIGHTING");
1862 glDisable(GL_LIGHTING
);
1863 checkGLcall("glDisable GL_LIGHTING");
1867 case WINED3DRS_ZENABLE
:
1868 switch ((D3DZBUFFERTYPE
) Value
) {
1870 glDisable(GL_DEPTH_TEST
);
1871 checkGLcall("glDisable GL_DEPTH_TEST");
1874 glEnable(GL_DEPTH_TEST
);
1875 checkGLcall("glEnable GL_DEPTH_TEST");
1878 glEnable(GL_DEPTH_TEST
);
1879 checkGLcall("glEnable GL_DEPTH_TEST");
1880 FIXME("W buffer is not well handled\n");
1883 FIXME("Unrecognized D3DZBUFFERTYPE value %ld\n", Value
);
1887 case WINED3DRS_CULLMODE
:
1889 /* If we are culling "back faces with clockwise vertices" then
1890 set front faces to be counter clockwise and enable culling
1892 switch ((D3DCULL
) Value
) {
1894 glDisable(GL_CULL_FACE
);
1895 checkGLcall("glDisable GL_CULL_FACE");
1898 glEnable(GL_CULL_FACE
);
1899 checkGLcall("glEnable GL_CULL_FACE");
1900 if (This
->renderUpsideDown
) {
1902 checkGLcall("glFrontFace GL_CW");
1904 glFrontFace(GL_CCW
);
1905 checkGLcall("glFrontFace GL_CCW");
1907 glCullFace(GL_BACK
);
1910 glEnable(GL_CULL_FACE
);
1911 checkGLcall("glEnable GL_CULL_FACE");
1912 if (This
->renderUpsideDown
) {
1913 glFrontFace(GL_CCW
);
1914 checkGLcall("glFrontFace GL_CCW");
1917 checkGLcall("glFrontFace GL_CW");
1919 glCullFace(GL_BACK
);
1922 FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value
);
1926 case WINED3DRS_SHADEMODE
:
1927 switch ((D3DSHADEMODE
) Value
) {
1929 glShadeModel(GL_FLAT
);
1930 checkGLcall("glShadeModel");
1932 case D3DSHADE_GOURAUD
:
1933 glShadeModel(GL_SMOOTH
);
1934 checkGLcall("glShadeModel");
1936 case D3DSHADE_PHONG
:
1937 FIXME("D3DSHADE_PHONG isn't supported?\n");
1940 return D3DERR_INVALIDCALL
;
1942 FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value
);
1946 case WINED3DRS_DITHERENABLE
:
1948 glEnable(GL_DITHER
);
1949 checkGLcall("glEnable GL_DITHER");
1951 glDisable(GL_DITHER
);
1952 checkGLcall("glDisable GL_DITHER");
1956 case WINED3DRS_ZWRITEENABLE
:
1959 checkGLcall("glDepthMask");
1962 checkGLcall("glDepthMask");
1966 case WINED3DRS_ZFUNC
:
1968 int glParm
= GL_LESS
;
1970 switch ((D3DCMPFUNC
) Value
) {
1971 case D3DCMP_NEVER
: glParm
=GL_NEVER
; break;
1972 case D3DCMP_LESS
: glParm
=GL_LESS
; break;
1973 case D3DCMP_EQUAL
: glParm
=GL_EQUAL
; break;
1974 case D3DCMP_LESSEQUAL
: glParm
=GL_LEQUAL
; break;
1975 case D3DCMP_GREATER
: glParm
=GL_GREATER
; break;
1976 case D3DCMP_NOTEQUAL
: glParm
=GL_NOTEQUAL
; break;
1977 case D3DCMP_GREATEREQUAL
: glParm
=GL_GEQUAL
; break;
1978 case D3DCMP_ALWAYS
: glParm
=GL_ALWAYS
; break;
1980 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value
);
1982 glDepthFunc(glParm
);
1983 checkGLcall("glDepthFunc");
1987 case WINED3DRS_AMBIENT
:
1990 D3DCOLORTOGLFLOAT4(Value
, col
);
1991 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col
[0], col
[1], col
[2], col
[3]);
1992 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, col
);
1993 checkGLcall("glLightModel for MODEL_AMBIENT");
1998 case WINED3DRS_ALPHABLENDENABLE
:
2001 checkGLcall("glEnable GL_BLEND");
2003 glDisable(GL_BLEND
);
2004 checkGLcall("glDisable GL_BLEND");
2008 case WINED3DRS_SRCBLEND
:
2009 case WINED3DRS_DESTBLEND
:
2011 int newVal
= GL_ZERO
;
2013 case D3DBLEND_ZERO
: newVal
= GL_ZERO
; break;
2014 case D3DBLEND_ONE
: newVal
= GL_ONE
; break;
2015 case D3DBLEND_SRCCOLOR
: newVal
= GL_SRC_COLOR
; break;
2016 case D3DBLEND_INVSRCCOLOR
: newVal
= GL_ONE_MINUS_SRC_COLOR
; break;
2017 case D3DBLEND_SRCALPHA
: newVal
= GL_SRC_ALPHA
; break;
2018 case D3DBLEND_INVSRCALPHA
: newVal
= GL_ONE_MINUS_SRC_ALPHA
; break;
2019 case D3DBLEND_DESTALPHA
: newVal
= GL_DST_ALPHA
; break;
2020 case D3DBLEND_INVDESTALPHA
: newVal
= GL_ONE_MINUS_DST_ALPHA
; break;
2021 case D3DBLEND_DESTCOLOR
: newVal
= GL_DST_COLOR
; break;
2022 case D3DBLEND_INVDESTCOLOR
: newVal
= GL_ONE_MINUS_DST_COLOR
; break;
2023 case D3DBLEND_SRCALPHASAT
: newVal
= GL_SRC_ALPHA_SATURATE
; break;
2025 case D3DBLEND_BOTHSRCALPHA
: newVal
= GL_SRC_ALPHA
;
2026 This
->srcBlend
= newVal
;
2027 This
->dstBlend
= newVal
;
2030 case D3DBLEND_BOTHINVSRCALPHA
: newVal
= GL_ONE_MINUS_SRC_ALPHA
;
2031 This
->srcBlend
= newVal
;
2032 This
->dstBlend
= newVal
;
2035 FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value
, State
);
2038 if (State
== WINED3DRS_SRCBLEND
) This
->srcBlend
= newVal
;
2039 if (State
== WINED3DRS_DESTBLEND
) This
->dstBlend
= newVal
;
2040 TRACE("glBlendFunc src=%x, dst=%x\n", This
->srcBlend
, This
->dstBlend
);
2041 glBlendFunc(This
->srcBlend
, This
->dstBlend
);
2043 checkGLcall("glBlendFunc");
2047 case WINED3DRS_ALPHATESTENABLE
:
2049 glEnable(GL_ALPHA_TEST
);
2050 checkGLcall("glEnable GL_ALPHA_TEST");
2052 glDisable(GL_ALPHA_TEST
);
2053 checkGLcall("glDisable GL_ALPHA_TEST");
2057 case WINED3DRS_ALPHAFUNC
:
2059 int glParm
= GL_LESS
;
2060 float ref
= ((float) This
->stateBlock
->renderState
[WINED3DRS_ALPHAREF
]) / 255.0f
;
2062 switch ((D3DCMPFUNC
) Value
) {
2063 case D3DCMP_NEVER
: glParm
= GL_NEVER
; break;
2064 case D3DCMP_LESS
: glParm
= GL_LESS
; break;
2065 case D3DCMP_EQUAL
: glParm
= GL_EQUAL
; break;
2066 case D3DCMP_LESSEQUAL
: glParm
= GL_LEQUAL
; break;
2067 case D3DCMP_GREATER
: glParm
= GL_GREATER
; break;
2068 case D3DCMP_NOTEQUAL
: glParm
= GL_NOTEQUAL
; break;
2069 case D3DCMP_GREATEREQUAL
: glParm
= GL_GEQUAL
; break;
2070 case D3DCMP_ALWAYS
: glParm
= GL_ALWAYS
; break;
2072 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value
);
2074 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm
, ref
);
2075 glAlphaFunc(glParm
, ref
);
2076 This
->alphafunc
= glParm
;
2077 checkGLcall("glAlphaFunc");
2081 case WINED3DRS_ALPHAREF
:
2083 int glParm
= This
->alphafunc
;
2086 ref
= ((float) Value
) / 255.0f
;
2087 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm
, ref
);
2088 glAlphaFunc(glParm
, ref
);
2089 checkGLcall("glAlphaFunc");
2093 case WINED3DRS_CLIPPLANEENABLE
:
2094 case WINED3DRS_CLIPPING
:
2096 /* Ensure we only do the changed clip planes */
2097 DWORD enable
= 0xFFFFFFFF;
2098 DWORD disable
= 0x00000000;
2100 /* If enabling / disabling all */
2101 if (State
== WINED3DRS_CLIPPING
) {
2103 enable
= This
->stateBlock
->renderState
[WINED3DRS_CLIPPLANEENABLE
];
2106 disable
= This
->stateBlock
->renderState
[WINED3DRS_CLIPPLANEENABLE
];
2110 enable
= Value
& ~OldValue
;
2111 disable
= ~Value
& OldValue
;
2114 if (enable
& D3DCLIPPLANE0
) { glEnable(GL_CLIP_PLANE0
); checkGLcall("glEnable(clip plane 0)"); }
2115 if (enable
& D3DCLIPPLANE1
) { glEnable(GL_CLIP_PLANE1
); checkGLcall("glEnable(clip plane 1)"); }
2116 if (enable
& D3DCLIPPLANE2
) { glEnable(GL_CLIP_PLANE2
); checkGLcall("glEnable(clip plane 2)"); }
2117 if (enable
& D3DCLIPPLANE3
) { glEnable(GL_CLIP_PLANE3
); checkGLcall("glEnable(clip plane 3)"); }
2118 if (enable
& D3DCLIPPLANE4
) { glEnable(GL_CLIP_PLANE4
); checkGLcall("glEnable(clip plane 4)"); }
2119 if (enable
& D3DCLIPPLANE5
) { glEnable(GL_CLIP_PLANE5
); checkGLcall("glEnable(clip plane 5)"); }
2121 if (disable
& D3DCLIPPLANE0
) { glDisable(GL_CLIP_PLANE0
); checkGLcall("glDisable(clip plane 0)"); }
2122 if (disable
& D3DCLIPPLANE1
) { glDisable(GL_CLIP_PLANE1
); checkGLcall("glDisable(clip plane 1)"); }
2123 if (disable
& D3DCLIPPLANE2
) { glDisable(GL_CLIP_PLANE2
); checkGLcall("glDisable(clip plane 2)"); }
2124 if (disable
& D3DCLIPPLANE3
) { glDisable(GL_CLIP_PLANE3
); checkGLcall("glDisable(clip plane 3)"); }
2125 if (disable
& D3DCLIPPLANE4
) { glDisable(GL_CLIP_PLANE4
); checkGLcall("glDisable(clip plane 4)"); }
2126 if (disable
& D3DCLIPPLANE5
) { glDisable(GL_CLIP_PLANE5
); checkGLcall("glDisable(clip plane 5)"); }
2128 /** update clipping status */
2130 This
->stateBlock
->clip_status
.ClipUnion
= 0;
2131 This
->stateBlock
->clip_status
.ClipIntersection
= 0xFFFFFFFF;
2133 This
->stateBlock
->clip_status
.ClipUnion
= 0;
2134 This
->stateBlock
->clip_status
.ClipIntersection
= 0;
2139 case WINED3DRS_BLENDOP
:
2141 int glParm
= GL_FUNC_ADD
;
2143 switch ((D3DBLENDOP
) Value
) {
2144 case D3DBLENDOP_ADD
: glParm
= GL_FUNC_ADD
; break;
2145 case D3DBLENDOP_SUBTRACT
: glParm
= GL_FUNC_SUBTRACT
; break;
2146 case D3DBLENDOP_REVSUBTRACT
: glParm
= GL_FUNC_REVERSE_SUBTRACT
; break;
2147 case D3DBLENDOP_MIN
: glParm
= GL_MIN
; break;
2148 case D3DBLENDOP_MAX
: glParm
= GL_MAX
; break;
2150 FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value
);
2152 TRACE("glBlendEquation(%x)\n", glParm
);
2153 glBlendEquation(glParm
);
2154 checkGLcall("glBlendEquation");
2158 case WINED3DRS_TEXTUREFACTOR
:
2162 /* Note the texture color applies to all textures whereas
2163 GL_TEXTURE_ENV_COLOR applies to active only */
2165 D3DCOLORTOGLFLOAT4(Value
, col
);
2166 /* Set the default alpha blend color */
2167 glBlendColor(col
[0], col
[1], col
[2], col
[3]);
2168 checkGLcall("glBlendColor");
2170 /* And now the default texture color as well */
2171 for (i
= 0; i
< GL_LIMITS(textures
); i
++) {
2173 /* Note the D3DRS value applies to all textures, but GL has one
2174 per texture, so apply it now ready to be used! */
2175 if (GL_SUPPORT(ARB_MULTITEXTURE
)) {
2178 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
2181 glTexEnvfv(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_COLOR
, &col
[0]);
2182 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
2187 case WINED3DRS_SPECULARENABLE
:
2189 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
2190 and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
2191 specular color. This is wrong:
2192 Separate specular color means the specular colour is maintained separately, whereas
2193 single color means it is merged in. However in both cases they are being used to
2195 To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
2196 NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
2200 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, (float*) &This
->updateStateBlock
->material
.Specular
);
2201 checkGLcall("glMaterialfv");
2202 if (GL_SUPPORT(EXT_SECONDARY_COLOR
)) {
2203 glEnable(GL_COLOR_SUM_EXT
);
2205 TRACE("Specular colors cannot be enabled in this version of opengl\n");
2207 checkGLcall("glEnable(GL_COLOR_SUM)");
2209 float black
[4] = {0.0f
, 0.0f
, 0.0f
, 0.0f
};
2211 /* for the case of enabled lighting: */
2212 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, &black
[0]);
2213 checkGLcall("glMaterialfv");
2215 /* for the case of disabled lighting: */
2216 if (GL_SUPPORT(EXT_SECONDARY_COLOR
)) {
2217 glDisable(GL_COLOR_SUM_EXT
);
2219 TRACE("Specular colors cannot be disabled in this version of opengl\n");
2221 checkGLcall("glDisable(GL_COLOR_SUM)");
2226 case WINED3DRS_STENCILENABLE
:
2228 glEnable(GL_STENCIL_TEST
);
2229 checkGLcall("glEnable GL_STENCIL_TEST");
2231 glDisable(GL_STENCIL_TEST
);
2232 checkGLcall("glDisable GL_STENCIL_TEST");
2236 case WINED3DRS_STENCILFUNC
:
2238 int glParm
= GL_ALWAYS
;
2239 int ref
= This
->stateBlock
->renderState
[WINED3DRS_STENCILREF
];
2240 GLuint mask
= This
->stateBlock
->renderState
[WINED3DRS_STENCILMASK
];
2242 switch ((D3DCMPFUNC
) Value
) {
2243 case D3DCMP_NEVER
: glParm
=GL_NEVER
; break;
2244 case D3DCMP_LESS
: glParm
=GL_LESS
; break;
2245 case D3DCMP_EQUAL
: glParm
=GL_EQUAL
; break;
2246 case D3DCMP_LESSEQUAL
: glParm
=GL_LEQUAL
; break;
2247 case D3DCMP_GREATER
: glParm
=GL_GREATER
; break;
2248 case D3DCMP_NOTEQUAL
: glParm
=GL_NOTEQUAL
; break;
2249 case D3DCMP_GREATEREQUAL
: glParm
=GL_GEQUAL
; break;
2250 case D3DCMP_ALWAYS
: glParm
=GL_ALWAYS
; break;
2252 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value
);
2254 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm
, ref
, mask
);
2255 This
->stencilfunc
= glParm
;
2256 glStencilFunc(glParm
, ref
, mask
);
2257 checkGLcall("glStencilFunc");
2261 case WINED3DRS_STENCILREF
:
2263 int glParm
= This
->stencilfunc
;
2265 GLuint mask
= This
->stateBlock
->renderState
[WINED3DRS_STENCILMASK
];
2268 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm
, ref
, mask
);
2269 glStencilFunc(glParm
, ref
, mask
);
2270 checkGLcall("glStencilFunc");
2274 case WINED3DRS_STENCILMASK
:
2276 int glParm
= This
->stencilfunc
;
2277 int ref
= This
->stateBlock
->renderState
[WINED3DRS_STENCILREF
];
2278 GLuint mask
= Value
;
2280 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm
, ref
, mask
);
2281 glStencilFunc(glParm
, ref
, mask
);
2282 checkGLcall("glStencilFunc");
2286 case WINED3DRS_STENCILFAIL
:
2292 fail
= StencilOp(Value
);
2293 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS
, &zpass
);
2294 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2295 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL
, &zfail
);
2296 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2298 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail
, zfail
, zpass
);
2299 glStencilOp(fail
, zfail
, zpass
);
2300 checkGLcall("glStencilOp(fail, zfail, zpass);");
2303 case WINED3DRS_STENCILZFAIL
:
2309 glGetIntegerv(GL_STENCIL_FAIL
, &fail
);
2310 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2311 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS
, &zpass
);
2312 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2313 zfail
= StencilOp(Value
);
2315 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail
, zfail
, zpass
);
2316 glStencilOp(fail
, zfail
, zpass
);
2317 checkGLcall("glStencilOp(fail, zfail, zpass);");
2320 case WINED3DRS_STENCILPASS
:
2326 glGetIntegerv(GL_STENCIL_FAIL
, &fail
);
2327 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2328 zpass
= StencilOp(Value
);
2329 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL
, &zfail
);
2330 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2332 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail
, zfail
, zpass
);
2333 glStencilOp(fail
, zfail
, zpass
);
2334 checkGLcall("glStencilOp(fail, zfail, zpass);");
2338 case WINED3DRS_STENCILWRITEMASK
:
2340 glStencilMask(Value
);
2341 TRACE("glStencilMask(%lu)\n", Value
);
2342 checkGLcall("glStencilMask");
2346 case WINED3DRS_FOGENABLE
:
2348 if (Value
/* && This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] != D3DFOG_NONE*/) {
2350 checkGLcall("glEnable GL_FOG");
2353 checkGLcall("glDisable GL_FOG");
2358 case WINED3DRS_RANGEFOGENABLE
:
2361 TRACE("Enabled RANGEFOG");
2363 TRACE("Disabled RANGEFOG");
2368 case WINED3DRS_FOGCOLOR
:
2371 D3DCOLORTOGLFLOAT4(Value
, col
);
2372 /* Set the default alpha blend color */
2373 glFogfv(GL_FOG_COLOR
, &col
[0]);
2374 checkGLcall("glFog GL_FOG_COLOR");
2378 case WINED3DRS_FOGTABLEMODE
:
2380 glHint(GL_FOG_HINT
, GL_NICEST
);
2382 case D3DFOG_NONE
: /* I don't know what to do here */ checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
2383 case D3DFOG_EXP
: glFogi(GL_FOG_MODE
, GL_EXP
); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
2384 case D3DFOG_EXP2
: glFogi(GL_FOG_MODE
, GL_EXP2
); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2"); break;
2385 case D3DFOG_LINEAR
: glFogi(GL_FOG_MODE
, GL_LINEAR
); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR"); break;
2387 FIXME("Unsupported Value(%lu) for WINED3DRS_FOGTABLEMODE!\n", Value
);
2389 if (GL_SUPPORT(NV_FOG_DISTANCE
)) {
2390 glFogi(GL_FOG_DISTANCE_MODE_NV
, GL_EYE_PLANE_ABSOLUTE_NV
);
2395 case WINED3DRS_FOGVERTEXMODE
:
2397 glHint(GL_FOG_HINT
, GL_FASTEST
);
2399 case D3DFOG_NONE
: /* I don't know what to do here */ checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
2400 case D3DFOG_EXP
: glFogi(GL_FOG_MODE
, GL_EXP
); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
2401 case D3DFOG_EXP2
: glFogi(GL_FOG_MODE
, GL_EXP2
); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2"); break;
2402 case D3DFOG_LINEAR
: glFogi(GL_FOG_MODE
, GL_LINEAR
); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR"); break;
2404 FIXME("Unsupported Value(%lu) for WINED3DRS_FOGTABLEMODE!\n", Value
);
2406 if (GL_SUPPORT(NV_FOG_DISTANCE
)) {
2407 glFogi(GL_FOG_DISTANCE_MODE_NV
, This
->stateBlock
->renderState
[WINED3DRS_RANGEFOGENABLE
] ? GL_EYE_RADIAL_NV
: GL_EYE_PLANE_ABSOLUTE_NV
);
2412 case WINED3DRS_FOGSTART
:
2415 glFogfv(GL_FOG_START
, &tmpvalue
.f
);
2416 checkGLcall("glFogf(GL_FOG_START, (float) Value)");
2417 TRACE("Fog Start == %f\n", tmpvalue
.f
);
2421 case WINED3DRS_FOGEND
:
2424 glFogfv(GL_FOG_END
, &tmpvalue
.f
);
2425 checkGLcall("glFogf(GL_FOG_END, (float) Value)");
2426 TRACE("Fog End == %f\n", tmpvalue
.f
);
2430 case WINED3DRS_FOGDENSITY
:
2433 glFogfv(GL_FOG_DENSITY
, &tmpvalue
.f
);
2434 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
2438 case WINED3DRS_VERTEXBLEND
:
2440 This
->updateStateBlock
->vertex_blend
= (D3DVERTEXBLENDFLAGS
) Value
;
2441 TRACE("Vertex Blending state to %ld\n", Value
);
2445 case WINED3DRS_TWEENFACTOR
:
2448 This
->updateStateBlock
->tween_factor
= tmpvalue
.f
;
2449 TRACE("Vertex Blending Tween Factor to %f\n", This
->updateStateBlock
->tween_factor
);
2453 case WINED3DRS_INDEXEDVERTEXBLENDENABLE
:
2455 TRACE("Indexed Vertex Blend Enable to %ul\n", (BOOL
) Value
);
2459 case WINED3DRS_COLORVERTEX
:
2460 case WINED3DRS_DIFFUSEMATERIALSOURCE
:
2461 case WINED3DRS_SPECULARMATERIALSOURCE
:
2462 case WINED3DRS_AMBIENTMATERIALSOURCE
:
2463 case WINED3DRS_EMISSIVEMATERIALSOURCE
:
2465 GLenum Parm
= GL_AMBIENT_AND_DIFFUSE
;
2467 if (This
->stateBlock
->renderState
[WINED3DRS_COLORVERTEX
]) {
2468 TRACE("diff %ld, amb %ld, emis %ld, spec %ld\n",
2469 This
->stateBlock
->renderState
[WINED3DRS_DIFFUSEMATERIALSOURCE
],
2470 This
->stateBlock
->renderState
[WINED3DRS_AMBIENTMATERIALSOURCE
],
2471 This
->stateBlock
->renderState
[WINED3DRS_EMISSIVEMATERIALSOURCE
],
2472 This
->stateBlock
->renderState
[WINED3DRS_SPECULARMATERIALSOURCE
]);
2474 if (This
->stateBlock
->renderState
[WINED3DRS_DIFFUSEMATERIALSOURCE
] == D3DMCS_COLOR1
) {
2475 if (This
->stateBlock
->renderState
[WINED3DRS_AMBIENTMATERIALSOURCE
] == D3DMCS_COLOR1
) {
2476 Parm
= GL_AMBIENT_AND_DIFFUSE
;
2480 } else if (This
->stateBlock
->renderState
[WINED3DRS_AMBIENTMATERIALSOURCE
] == D3DMCS_COLOR1
) {
2482 } else if (This
->stateBlock
->renderState
[WINED3DRS_EMISSIVEMATERIALSOURCE
] == D3DMCS_COLOR1
) {
2484 } else if (This
->stateBlock
->renderState
[WINED3DRS_SPECULARMATERIALSOURCE
] == D3DMCS_COLOR1
) {
2491 if (This
->tracking_color
!= DISABLED_TRACKING
) This
->tracking_color
= NEEDS_DISABLE
;
2493 This
->tracking_color
= NEEDS_TRACKING
;
2494 This
->tracking_parm
= Parm
;
2498 if (This
->tracking_color
!= DISABLED_TRACKING
) This
->tracking_color
= NEEDS_DISABLE
;
2503 case WINED3DRS_LINEPATTERN
:
2509 tmppattern
.d
= Value
;
2511 TRACE("Line pattern: repeat %d bits %x\n", tmppattern
.lp
.wRepeatFactor
, tmppattern
.lp
.wLinePattern
);
2513 if (tmppattern
.lp
.wRepeatFactor
) {
2514 glLineStipple(tmppattern
.lp
.wRepeatFactor
, tmppattern
.lp
.wLinePattern
);
2515 checkGLcall("glLineStipple(repeat, linepattern)");
2516 glEnable(GL_LINE_STIPPLE
);
2517 checkGLcall("glEnable(GL_LINE_STIPPLE);");
2519 glDisable(GL_LINE_STIPPLE
);
2520 checkGLcall("glDisable(GL_LINE_STIPPLE);");
2525 case WINED3DRS_ZBIAS
:
2529 TRACE("ZBias value %f\n", tmpvalue
.f
);
2530 glPolygonOffset(0, -tmpvalue
.f
);
2531 checkGLcall("glPolygonOffset(0, -Value)");
2532 glEnable(GL_POLYGON_OFFSET_FILL
);
2533 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
2534 glEnable(GL_POLYGON_OFFSET_LINE
);
2535 checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
2536 glEnable(GL_POLYGON_OFFSET_POINT
);
2537 checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
2539 glDisable(GL_POLYGON_OFFSET_FILL
);
2540 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
2541 glDisable(GL_POLYGON_OFFSET_LINE
);
2542 checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
2543 glDisable(GL_POLYGON_OFFSET_POINT
);
2544 checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
2549 case WINED3DRS_NORMALIZENORMALS
:
2551 glEnable(GL_NORMALIZE
);
2552 checkGLcall("glEnable(GL_NORMALIZE);");
2554 glDisable(GL_NORMALIZE
);
2555 checkGLcall("glDisable(GL_NORMALIZE);");
2559 case WINED3DRS_POINTSIZE
:
2561 TRACE("Set point size to %f\n", tmpvalue
.f
);
2562 glPointSize(tmpvalue
.f
);
2563 checkGLcall("glPointSize(...);");
2566 case WINED3DRS_POINTSIZE_MIN
:
2567 if (GL_SUPPORT(EXT_POINT_PARAMETERS
)) {
2569 GL_EXTCALL(glPointParameterfEXT
)(GL_POINT_SIZE_MIN_EXT
, tmpvalue
.f
);
2570 checkGLcall("glPointParameterfEXT(...);");
2572 FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl\n");
2576 case WINED3DRS_POINTSIZE_MAX
:
2577 if (GL_SUPPORT(EXT_POINT_PARAMETERS
)) {
2579 GL_EXTCALL(glPointParameterfEXT
)(GL_POINT_SIZE_MAX_EXT
, tmpvalue
.f
);
2580 checkGLcall("glPointParameterfEXT(...);");
2582 FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl\n");
2586 case WINED3DRS_POINTSCALE_A
:
2587 case WINED3DRS_POINTSCALE_B
:
2588 case WINED3DRS_POINTSCALE_C
:
2589 case WINED3DRS_POINTSCALEENABLE
:
2591 /* If enabled, supply the parameters, otherwise fall back to defaults */
2592 if (This
->stateBlock
->renderState
[WINED3DRS_POINTSCALEENABLE
]) {
2593 GLfloat att
[3] = {1.0f
, 0.0f
, 0.0f
};
2594 att
[0] = *((float*)&This
->stateBlock
->renderState
[WINED3DRS_POINTSCALE_A
]);
2595 att
[1] = *((float*)&This
->stateBlock
->renderState
[WINED3DRS_POINTSCALE_B
]);
2596 att
[2] = *((float*)&This
->stateBlock
->renderState
[WINED3DRS_POINTSCALE_C
]);
2598 if (GL_SUPPORT(EXT_POINT_PARAMETERS
)) {
2599 GL_EXTCALL(glPointParameterfvEXT
)(GL_DISTANCE_ATTENUATION_EXT
, att
);
2600 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...);");
2602 TRACE("WINED3DRS_POINTSCALEENABLE not supported on this opengl\n");
2605 GLfloat att
[3] = {1.0f
, 0.0f
, 0.0f
};
2606 if (GL_SUPPORT(EXT_POINT_PARAMETERS
)) {
2607 GL_EXTCALL(glPointParameterfvEXT
)(GL_DISTANCE_ATTENUATION_EXT
, att
);
2608 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...);");
2610 TRACE("WINED3DRS_POINTSCALEENABLE not supported, but not on either\n");
2616 case WINED3DRS_COLORWRITEENABLE
:
2618 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
2619 Value
& D3DCOLORWRITEENABLE_RED
? 1 : 0,
2620 Value
& D3DCOLORWRITEENABLE_GREEN
? 1 : 0,
2621 Value
& D3DCOLORWRITEENABLE_BLUE
? 1 : 0,
2622 Value
& D3DCOLORWRITEENABLE_ALPHA
? 1 : 0);
2623 glColorMask(Value
& D3DCOLORWRITEENABLE_RED
? GL_TRUE
: GL_FALSE
,
2624 Value
& D3DCOLORWRITEENABLE_GREEN
? GL_TRUE
: GL_FALSE
,
2625 Value
& D3DCOLORWRITEENABLE_BLUE
? GL_TRUE
: GL_FALSE
,
2626 Value
& D3DCOLORWRITEENABLE_ALPHA
? GL_TRUE
: GL_FALSE
);
2627 checkGLcall("glColorMask(...)");
2631 case WINED3DRS_LOCALVIEWER
:
2633 GLint state
= (Value
) ? 1 : 0;
2634 TRACE("Local Viewer Enable to %ul\n", (BOOL
) Value
);
2635 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER
, state
);
2639 case WINED3DRS_LASTPIXEL
:
2642 TRACE("Last Pixel Drawing Enabled\n");
2644 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
2649 case WINED3DRS_SOFTWAREVERTEXPROCESSING
:
2652 TRACE("Software Processing Enabled\n");
2654 TRACE("Software Processing Disabled\n");
2659 /** not supported */
2660 case WINED3DRS_ZVISIBLE
:
2663 return D3DERR_INVALIDCALL
;
2666 /* Unhandled yet...! */
2667 case WINED3DRS_EDGEANTIALIAS
:
2668 case WINED3DRS_WRAP0
:
2669 case WINED3DRS_WRAP1
:
2670 case WINED3DRS_WRAP2
:
2671 case WINED3DRS_WRAP3
:
2672 case WINED3DRS_WRAP4
:
2673 case WINED3DRS_WRAP5
:
2674 case WINED3DRS_WRAP6
:
2675 case WINED3DRS_WRAP7
:
2676 case WINED3DRS_POINTSPRITEENABLE
:
2677 case WINED3DRS_MULTISAMPLEANTIALIAS
:
2678 case WINED3DRS_MULTISAMPLEMASK
:
2679 case WINED3DRS_PATCHEDGESTYLE
:
2680 case WINED3DRS_PATCHSEGMENTS
:
2681 case WINED3DRS_DEBUGMONITORTOKEN
:
2682 case WINED3DRS_POSITIONORDER
:
2683 case WINED3DRS_NORMALORDER
:
2684 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
2685 FIXME("(%p)->(%d,%ld) not handled yet\n", This
, State
, Value
);
2688 FIXME("(%p)->(%d,%ld) unrecognized\n", This
, State
, Value
);
2696 HRESULT WINAPI
IWineD3DDeviceImpl_GetRenderState(IWineD3DDevice
*iface
, D3DRENDERSTATETYPE State
, DWORD
*pValue
) {
2697 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2698 TRACE("(%p) for State %d = %ld\n", This
, State
, This
->stateBlock
->renderState
[State
]);
2699 *pValue
= This
->stateBlock
->renderState
[State
];
2703 HRESULT WINAPI
IWineD3DDeviceImpl_SetSamplerState(IWineD3DDevice
*iface
, DWORD Sampler
, WINED3DSAMPLERSTATETYPE Type
, DWORD Value
){
2704 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2706 FIXME("(%p) : stub\n", This
);
2710 HRESULT WINAPI
IWineD3DDeviceImpl_GetSamplerState(IWineD3DDevice
*iface
, DWORD Sampler
, WINED3DSAMPLERSTATETYPE Type
, DWORD
* Value
){
2711 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2713 FIXME("(%p) : stub\n", This
);
2718 HRESULT WINAPI
IWineD3DDeviceImpl_SetScissorRect(IWineD3DDevice
*iface
, CONST RECT
* pRect
){
2719 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2722 /** FIXME: Windows uses a top,left origin openGL uses a bottom Right? **/
2723 TRACE("(%p)Setting new Scissor Rect to %ld:%ld-%ld:%ld\n", This
, pRect
->left
, pRect
->top
, pRect
->right
, pRect
->bottom
);
2724 glScissor(pRect
->left
, pRect
->top
, pRect
->right
- pRect
->left
, pRect
->bottom
- pRect
->top
);
2729 HRESULT WINAPI
IWineD3DDeviceImpl_GetScissorRect(IWineD3DDevice
*iface
, RECT
* pRect
){
2730 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2731 GLint scissorBox
[4];
2734 /** FIXME: Windows uses a top,left origin openGL uses a bottom Right? **/
2735 glGetIntegerv(GL_SCISSOR_BOX
, scissorBox
);
2736 pRect
->left
= scissorBox
[1];
2737 pRect
->top
= scissorBox
[2];
2738 pRect
->right
= scissorBox
[1] + scissorBox
[3];
2739 pRect
->bottom
= scissorBox
[2] + scissorBox
[4];
2740 TRACE("(%p)Returning a Scissor Rect of %ld:%ld-%ld:%ld\n", This
, pRect
->left
, pRect
->top
, pRect
->right
, pRect
->bottom
);
2745 HRESULT WINAPI
IWineD3DDeviceImpl_SetVertexDeclaration(IWineD3DDevice
* iface
, IWineD3DVertexDeclaration
* pDecl
) {
2746 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*) iface
;
2748 TRACE("(%p) : pDecl=%p\n", This
, pDecl
);
2750 IWineD3DVertexDeclaration_AddRef(pDecl
);
2751 if (NULL
!= This
->updateStateBlock
->vertexDecl
) {
2752 IWineD3DVertexDeclaration_Release(This
->updateStateBlock
->vertexDecl
);
2754 This
->updateStateBlock
->vertexDecl
= pDecl
;
2755 This
->updateStateBlock
->changed
.vertexDecl
= TRUE
;
2756 This
->updateStateBlock
->set
.vertexDecl
= TRUE
;
2760 HRESULT WINAPI
IWineD3DDeviceImpl_GetVertexDeclaration(IWineD3DDevice
* iface
, IWineD3DVertexDeclaration
** ppDecl
) {
2761 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2763 TRACE("(%p) : ppDecl=%p\n", This
, ppDecl
);
2765 *ppDecl
= This
->updateStateBlock
->vertexDecl
;
2766 if (NULL
!= *ppDecl
) IWineD3DVertexDeclaration_AddRef(*ppDecl
);
2770 HRESULT WINAPI
IWineD3DDeviceImpl_SetVertexShader(IWineD3DDevice
*iface
, IWineD3DVertexShader
* pShader
){
2771 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2773 static BOOL showFixmes
= TRUE
;
2775 This
->updateStateBlock
->vertexShader
= pShader
;
2776 This
->updateStateBlock
->changed
.vertexShader
= TRUE
;
2777 This
->updateStateBlock
->set
.vertexShader
= TRUE
;
2779 if(pShader
== NULL
){
2780 /* clear down the shader */
2781 TRACE("Clear down the shader\n");
2784 FIXME("(%p) : stub pShader(%p)\n", This
, pShader
);
2791 /** FIXME: refernece counting? **/
2792 if (pShader
== NULL
) { /* only valid with non FVF shaders */
2793 TRACE_(d3d_shader
)("(%p) : FVF Shader, pShader=%p\n", This
, pShader
);
2794 This
->updateStateBlock
->vertexShader
= NULL
;
2796 TRACE_(d3d_shader
)("(%p) : Created shader, pShader=%p\n", This
, pShader
);
2797 This
->updateStateBlock
->vertexShader
= pShader
;
2800 This
->updateStateBlock
->changed
.vertexShader
= TRUE
;
2801 This
->updateStateBlock
->set
.vertexShader
= TRUE
;
2803 /* Handle recording of state blocks */
2804 if (This
->isRecordingState
) {
2805 TRACE("Recording... not performing anything\n");
2809 * TODO: merge HAL shaders context switching from prototype
2815 HRESULT WINAPI
IWineD3DDeviceImpl_GetVertexShader(IWineD3DDevice
*iface
, IWineD3DVertexShader
** ppShader
){
2816 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2817 *ppShader
= This
->stateBlock
->vertexShader
;
2818 if(*ppShader
!= NULL
)
2819 IWineD3DVertexShader_AddRef(*ppShader
);
2820 TRACE("(%p) : returning %p\n", This
, *ppShader
);
2824 HRESULT WINAPI
IWineD3DDeviceImpl_SetVertexShaderConstantB(IWineD3DDevice
*iface
, UINT StartRegister
, CONST BOOL
*pConstantData
, UINT BoolCount
){
2825 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2827 TRACE("(%p) : stub\n", This
);
2831 HRESULT WINAPI
IWineD3DDeviceImpl_GetVertexShaderConstantB(IWineD3DDevice
*iface
, UINT StartRegister
, BOOL
*pConstantData
, UINT BoolCount
){
2832 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2833 TRACE("(%p) : stub\n", This
);
2837 HRESULT WINAPI
IWineD3DDeviceImpl_SetVertexShaderConstantI(IWineD3DDevice
*iface
, UINT StartRegister
, CONST
int *pConstantData
, UINT Vector4iCount
){
2838 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2839 TRACE("(%p) : stub\n", This
);
2843 HRESULT WINAPI
IWineD3DDeviceImpl_GetVertexShaderConstantI(IWineD3DDevice
*iface
, UINT StartRegister
, int *pConstantData
, UINT Vector4iCount
){
2844 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2845 TRACE("(%p) : stub\n", This
);
2849 HRESULT WINAPI
IWineD3DDeviceImpl_SetVertexShaderConstantF(IWineD3DDevice
*iface
, UINT StartRegister
, CONST
float *pConstantData
, UINT Vector4fCount
){
2850 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2851 TRACE("(%p) : stub\n", This
);
2855 HRESULT WINAPI
IWineD3DDeviceImpl_GetVertexShaderConstantF(IWineD3DDevice
*iface
, UINT StartRegister
, float *pConstantData
, UINT Vector4fCount
){
2856 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2857 TRACE("(%p) : stub\n", This
);
2861 HRESULT WINAPI
IWineD3DDeviceImpl_SetPixelShader(IWineD3DDevice
*iface
, IWineD3DPixelShader
*pShader
){
2862 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2863 TRACE("(%p) : stub\n", This
);
2867 HRESULT WINAPI
IWineD3DDeviceImpl_GetPixelShader(IWineD3DDevice
*iface
, IWineD3DPixelShader
**ppShader
){
2868 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2869 TRACE("(%p) : stub\n", This
);
2874 HRESULT WINAPI
IWineD3DDeviceImpl_SetPixelShaderConstantB(IWineD3DDevice
*iface
, UINT StartRegister
, CONST BOOL
*pConstantData
, UINT BoolCount
){
2875 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2876 TRACE("(%p) : stub\n", This
);
2880 HRESULT WINAPI
IWineD3DDeviceImpl_GetPixelShaderConstantB(IWineD3DDevice
*iface
, UINT StartRegister
, BOOL
*pConstantData
, UINT BoolCount
){
2881 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2882 TRACE("(%p) : stub\n", This
);
2886 HRESULT WINAPI
IWineD3DDeviceImpl_SetPixelShaderConstantI(IWineD3DDevice
*iface
, UINT StartRegister
, CONST
int *pConstantData
, UINT Vector4iCount
){
2887 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2888 TRACE("(%p) : stub\n", This
);
2892 HRESULT WINAPI
IWineD3DDeviceImpl_GetPixelShaderConstantI(IWineD3DDevice
*iface
, UINT StartRegister
, int *pConstantData
, UINT Vector4iCount
){
2893 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2894 TRACE("(%p) : stub\n", This
);
2898 HRESULT WINAPI
IWineD3DDeviceImpl_SetPixelShaderConstantF(IWineD3DDevice
*iface
, UINT StartRegister
, CONST
float *pConstantData
, UINT Vector4fCount
){
2899 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2900 TRACE("(%p) : stub\n", This
);
2904 HRESULT WINAPI
IWineD3DDeviceImpl_GetPixelShaderConstantF(IWineD3DDevice
*iface
, UINT StartRegister
, float *pConstantData
, UINT Vector4fCount
){
2905 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2906 TRACE("(%p) : stub\n", This
);
2910 HRESULT WINAPI
IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice
*iface
, UINT SrcStartIndex
, UINT DestIndex
, UINT VertexCount
, IWineD3DVertexBuffer
* pDestBuffer
, IWineD3DVertexBuffer
* pVertexDecl
, DWORD Flags
){
2911 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2912 FIXME("(%p) : stub\n", This
);
2917 * Get / Set Texture Stage States
2918 * TODO: Verify against dx9 definitions
2920 HRESULT WINAPI
IWineD3DDeviceImpl_SetTextureStageState(IWineD3DDevice
*iface
, DWORD Stage
, D3DTEXTURESTAGESTATETYPE Type
, DWORD Value
) {
2921 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
2927 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
2929 TRACE("(%p) : Stage=%ld, Type=%s(%d), Value=%ld\n", This
, Stage
, debug_d3dtexturestate(Type
), Type
, Value
);
2931 /* Reject invalid texture units */
2932 if (Stage
>= GL_LIMITS(textures
)) {
2933 TRACE("Attempt to access invalid texture rejected\n");
2934 return D3DERR_INVALIDCALL
;
2937 This
->updateStateBlock
->changed
.textureState
[Stage
][Type
] = TRUE
;
2938 This
->updateStateBlock
->set
.textureState
[Stage
][Type
] = TRUE
;
2939 This
->updateStateBlock
->textureState
[Stage
][Type
] = Value
;
2941 /* Handle recording of state blocks */
2942 if (This
->isRecordingState
) {
2943 TRACE("Recording... not performing anything\n");
2949 /* Make appropriate texture active */
2950 VTRACE(("Activating appropriate texture state %ld\n", Stage
));
2951 if (GL_SUPPORT(ARB_MULTITEXTURE
)) {
2952 GLACTIVETEXTURE(Stage
);
2953 } else if (Stage
> 0) {
2954 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
2959 case D3DTSS_MINFILTER
:
2960 case D3DTSS_MIPFILTER
:
2962 DWORD ValueMIN
= This
->stateBlock
->textureState
[Stage
][D3DTSS_MINFILTER
];
2963 DWORD ValueMIP
= This
->stateBlock
->textureState
[Stage
][D3DTSS_MIPFILTER
];
2964 GLint realVal
= GL_LINEAR
;
2966 if (ValueMIN
== D3DTEXF_NONE
) {
2967 /* Doesn't really make sense - Windows just seems to disable
2968 mipmapping when this occurs */
2969 FIXME("Odd - minfilter of none, just disabling mipmaps\n");
2970 realVal
= GL_LINEAR
;
2971 } else if (ValueMIN
== D3DTEXF_POINT
) {
2973 if (ValueMIP
== D3DTEXF_NONE
) {
2974 realVal
= GL_NEAREST
;
2975 } else if (ValueMIP
== D3DTEXF_POINT
) {
2976 realVal
= GL_NEAREST_MIPMAP_NEAREST
;
2977 } else if (ValueMIP
== D3DTEXF_LINEAR
) {
2978 realVal
= GL_NEAREST_MIPMAP_LINEAR
;
2980 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP
);
2981 realVal
= GL_NEAREST
;
2983 } else if (ValueMIN
== D3DTEXF_LINEAR
) {
2985 if (ValueMIP
== D3DTEXF_NONE
) {
2986 realVal
= GL_LINEAR
;
2987 } else if (ValueMIP
== D3DTEXF_POINT
) {
2988 realVal
= GL_LINEAR_MIPMAP_NEAREST
;
2989 } else if (ValueMIP
== D3DTEXF_LINEAR
) {
2990 realVal
= GL_LINEAR_MIPMAP_LINEAR
;
2992 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP
);
2993 realVal
= GL_LINEAR
;
2995 } else if (ValueMIN
== D3DTEXF_ANISOTROPIC
) {
2996 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
)) {
2997 if (ValueMIP
== D3DTEXF_NONE
) {
2998 realVal
= GL_LINEAR_MIPMAP_LINEAR
;
2999 } else if (ValueMIP
== D3DTEXF_POINT
) {
3000 realVal
= GL_LINEAR_MIPMAP_NEAREST
;
3001 } else if (ValueMIP
== D3DTEXF_LINEAR
) {
3002 realVal
= GL_LINEAR_MIPMAP_LINEAR
;
3004 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP
);
3005 realVal
= GL_LINEAR
;
3008 WARN("Trying to use ANISOTROPIC_FILTERING for D3DTSS_MINFILTER. But not supported by OpenGL driver\n");
3009 realVal
= GL_LINEAR
;
3012 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", ValueMIN
);
3013 realVal
= GL_LINEAR_MIPMAP_LINEAR
;
3016 TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN
, ValueMIP
, realVal
);
3017 glTexParameteri(This
->stateBlock
->textureDimensions
[Stage
], GL_TEXTURE_MIN_FILTER
, realVal
);
3018 checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
3020 * if we juste choose to use ANISOTROPIC filtering, refresh openGL state
3022 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
) && D3DTEXF_ANISOTROPIC
== ValueMIN
) {
3023 glTexParameteri(This
->stateBlock
->textureDimensions
[Stage
],
3024 GL_TEXTURE_MAX_ANISOTROPY_EXT
,
3025 This
->stateBlock
->textureState
[Stage
][D3DTSS_MAXANISOTROPY
]);
3026 checkGLcall("glTexParameter GL_TEXTURE_MAX_ANISOTROPY_EXT, ...");
3031 case D3DTSS_MAGFILTER
:
3033 DWORD ValueMAG
= This
->stateBlock
->textureState
[Stage
][D3DTSS_MAGFILTER
];
3034 GLint realVal
= GL_NEAREST
;
3036 if (ValueMAG
== D3DTEXF_POINT
) {
3037 realVal
= GL_NEAREST
;
3038 } else if (ValueMAG
== D3DTEXF_LINEAR
) {
3039 realVal
= GL_LINEAR
;
3040 } else if (ValueMAG
== D3DTEXF_ANISOTROPIC
) {
3041 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
)) {
3042 realVal
= GL_LINEAR
;
3044 FIXME("Trying to use ANISOTROPIC_FILTERING for D3DTSS_MAGFILTER. But not supported by current OpenGL driver\n");
3045 realVal
= GL_NEAREST
;
3048 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", ValueMAG
);
3049 realVal
= GL_NEAREST
;
3051 TRACE("ValueMAG=%ld setting MAGFILTER to %x\n", ValueMAG
, realVal
);
3052 glTexParameteri(This
->stateBlock
->textureDimensions
[Stage
], GL_TEXTURE_MAG_FILTER
, realVal
);
3053 checkGLcall("glTexParameter GL_TEXTURE_MAG_FILTER, ...");
3055 * if we juste choose to use ANISOTROPIC filtering, refresh openGL state
3057 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
) && D3DTEXF_ANISOTROPIC
== ValueMAG
) {
3058 glTexParameteri(This
->stateBlock
->textureDimensions
[Stage
],
3059 GL_TEXTURE_MAX_ANISOTROPY_EXT
,
3060 This
->stateBlock
->textureState
[Stage
][D3DTSS_MAXANISOTROPY
]);
3061 checkGLcall("glTexParameter GL_TEXTURE_MAX_ANISOTROPY_EXT, ...");
3066 case D3DTSS_MAXMIPLEVEL
:
3069 * Not really the same, but the more apprioprate than nothing
3071 glTexParameteri(This
->stateBlock
->textureDimensions
[Stage
],
3072 GL_TEXTURE_BASE_LEVEL
,
3073 This
->stateBlock
->textureState
[Stage
][D3DTSS_MAXMIPLEVEL
]);
3074 checkGLcall("glTexParameteri GL_TEXTURE_BASE_LEVEL ...");
3078 case D3DTSS_MAXANISOTROPY
:
3080 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
)) {
3081 glTexParameteri(This
->stateBlock
->textureDimensions
[Stage
],
3082 GL_TEXTURE_MAX_ANISOTROPY_EXT
,
3083 This
->stateBlock
->textureState
[Stage
][D3DTSS_MAXANISOTROPY
]);
3084 checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ...");
3089 case D3DTSS_MIPMAPLODBIAS
:
3091 if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS
)) {
3093 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT
,
3094 GL_TEXTURE_LOD_BIAS_EXT
,
3096 checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
3101 case D3DTSS_ALPHAOP
:
3102 case D3DTSS_COLOROP
:
3105 if ((Value
== D3DTOP_DISABLE
) && (Type
== D3DTSS_COLOROP
)) {
3106 /* TODO: Disable by making this and all later levels disabled */
3107 glDisable(GL_TEXTURE_1D
);
3108 checkGLcall("Disable GL_TEXTURE_1D");
3109 glDisable(GL_TEXTURE_2D
);
3110 checkGLcall("Disable GL_TEXTURE_2D");
3111 glDisable(GL_TEXTURE_3D
);
3112 checkGLcall("Disable GL_TEXTURE_3D");
3113 break; /* Don't bother setting the texture operations */
3115 /* Enable only the appropriate texture dimension */
3116 if (Type
== D3DTSS_COLOROP
) {
3117 if (This
->stateBlock
->textureDimensions
[Stage
] == GL_TEXTURE_1D
) {
3118 glEnable(GL_TEXTURE_1D
);
3119 checkGLcall("Enable GL_TEXTURE_1D");
3121 glDisable(GL_TEXTURE_1D
);
3122 checkGLcall("Disable GL_TEXTURE_1D");
3124 if (This
->stateBlock
->textureDimensions
[Stage
] == GL_TEXTURE_2D
) {
3125 if (GL_SUPPORT(NV_TEXTURE_SHADER
) && This
->texture_shader_active
) {
3126 glTexEnvi(GL_TEXTURE_SHADER_NV
, GL_SHADER_OPERATION_NV
, GL_TEXTURE_2D
);
3127 checkGLcall("Enable GL_TEXTURE_2D");
3129 glEnable(GL_TEXTURE_2D
);
3130 checkGLcall("Enable GL_TEXTURE_2D");
3133 glDisable(GL_TEXTURE_2D
);
3134 checkGLcall("Disable GL_TEXTURE_2D");
3136 if (This
->stateBlock
->textureDimensions
[Stage
] == GL_TEXTURE_3D
) {
3137 glEnable(GL_TEXTURE_3D
);
3138 checkGLcall("Enable GL_TEXTURE_3D");
3140 glDisable(GL_TEXTURE_3D
);
3141 checkGLcall("Disable GL_TEXTURE_3D");
3143 if (This
->stateBlock
->textureDimensions
[Stage
] == GL_TEXTURE_CUBE_MAP_ARB
) {
3144 glEnable(GL_TEXTURE_CUBE_MAP_ARB
);
3145 checkGLcall("Enable GL_TEXTURE_CUBE_MAP");
3147 glDisable(GL_TEXTURE_CUBE_MAP_ARB
);
3148 checkGLcall("Disable GL_TEXTURE_CUBE_MAP");
3152 /* Drop through... (Except disable case) */
3153 case D3DTSS_COLORARG0
:
3154 case D3DTSS_COLORARG1
:
3155 case D3DTSS_COLORARG2
:
3156 case D3DTSS_ALPHAARG0
:
3157 case D3DTSS_ALPHAARG1
:
3158 case D3DTSS_ALPHAARG2
:
3160 BOOL isAlphaArg
= (Type
== D3DTSS_ALPHAOP
|| Type
== D3DTSS_ALPHAARG1
||
3161 Type
== D3DTSS_ALPHAARG2
|| Type
== D3DTSS_ALPHAARG0
);
3163 set_tex_op(iface
, TRUE
, Stage
, This
->stateBlock
->textureState
[Stage
][D3DTSS_ALPHAOP
],
3164 This
->stateBlock
->textureState
[Stage
][D3DTSS_ALPHAARG1
],
3165 This
->stateBlock
->textureState
[Stage
][D3DTSS_ALPHAARG2
],
3166 This
->stateBlock
->textureState
[Stage
][D3DTSS_ALPHAARG0
]);
3168 set_tex_op(iface
, FALSE
, Stage
, This
->stateBlock
->textureState
[Stage
][D3DTSS_COLOROP
],
3169 This
->stateBlock
->textureState
[Stage
][D3DTSS_COLORARG1
],
3170 This
->stateBlock
->textureState
[Stage
][D3DTSS_COLORARG2
],
3171 This
->stateBlock
->textureState
[Stage
][D3DTSS_COLORARG0
]);
3177 case D3DTSS_ADDRESSU
:
3178 case D3DTSS_ADDRESSV
:
3179 case D3DTSS_ADDRESSW
:
3181 GLint wrapParm
= GL_REPEAT
;
3184 case D3DTADDRESS_WRAP
: wrapParm
= GL_REPEAT
; break;
3185 case D3DTADDRESS_CLAMP
: wrapParm
= GL_CLAMP_TO_EDGE
; break;
3186 case D3DTADDRESS_BORDER
:
3188 if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP
)) {
3189 wrapParm
= GL_CLAMP_TO_BORDER_ARB
;
3191 /* FIXME: Not right, but better */
3192 FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value
, Type
);
3193 wrapParm
= GL_REPEAT
;
3197 case D3DTADDRESS_MIRROR
:
3199 if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT
)) {
3200 wrapParm
= GL_MIRRORED_REPEAT_ARB
;
3202 /* Unsupported in OpenGL pre-1.4 */
3203 FIXME("Unsupported D3DTADDRESS_MIRROR (needs GL_ARB_texture_mirrored_repeat) state %d\n", Type
);
3204 wrapParm
= GL_REPEAT
;
3208 case D3DTADDRESS_MIRRORONCE
:
3210 if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE
)) {
3211 wrapParm
= GL_MIRROR_CLAMP_TO_EDGE_ATI
;
3213 FIXME("Unsupported D3DTADDRESS_MIRRORONCE (needs GL_ATI_texture_mirror_once) state %d\n", Type
);
3214 wrapParm
= GL_REPEAT
;
3220 FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value
, Type
);
3221 wrapParm
= GL_REPEAT
;
3225 case D3DTSS_ADDRESSU
:
3226 TRACE("Setting WRAP_S to %d for %x\n", wrapParm
, This
->stateBlock
->textureDimensions
[Stage
]);
3227 glTexParameteri(This
->stateBlock
->textureDimensions
[Stage
], GL_TEXTURE_WRAP_S
, wrapParm
);
3228 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)");
3230 case D3DTSS_ADDRESSV
:
3231 TRACE("Setting WRAP_T to %d for %x\n", wrapParm
, This
->stateBlock
->textureDimensions
[Stage
]);
3232 glTexParameteri(This
->stateBlock
->textureDimensions
[Stage
], GL_TEXTURE_WRAP_T
, wrapParm
);
3233 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)");
3235 case D3DTSS_ADDRESSW
:
3236 TRACE("Setting WRAP_R to %d for %x\n", wrapParm
, This
->stateBlock
->textureDimensions
[Stage
]);
3237 glTexParameteri(This
->stateBlock
->textureDimensions
[Stage
], GL_TEXTURE_WRAP_R
, wrapParm
);
3238 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
3241 break; /** stupic compilator */
3246 case D3DTSS_BORDERCOLOR
:
3249 D3DCOLORTOGLFLOAT4(Value
, col
);
3250 TRACE("Setting border color for %x to %lx\n", This
->stateBlock
->textureDimensions
[Stage
], Value
);
3251 glTexParameterfv(This
->stateBlock
->textureDimensions
[Stage
], GL_TEXTURE_BORDER_COLOR
, &col
[0]);
3252 checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
3256 case D3DTSS_TEXCOORDINDEX
:
3258 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive */
3260 /* FIXME: From MSDN: The D3DTSS_TCI_* flags are mutually exclusive. If you include
3261 one flag, you can still specify an index value, which the system uses to
3262 determine the texture wrapping mode.
3263 eg. SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION | 1 );
3264 means use the vertex position (camera-space) as the input texture coordinates
3265 for this texture stage, and the wrap mode set in the WINED3DRS_WRAP1 render
3266 state. We do not (yet) support the D3DRENDERSTATE_WRAPx values, nor tie them up
3267 to the TEXCOORDINDEX value */
3270 * Be careful the value of the mask 0xF0000 come from d3d8types.h infos
3272 switch (Value
& 0xFFFF0000) {
3273 case D3DTSS_TCI_PASSTHRU
:
3274 /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
3275 glDisable(GL_TEXTURE_GEN_S
);
3276 glDisable(GL_TEXTURE_GEN_T
);
3277 glDisable(GL_TEXTURE_GEN_R
);
3278 checkGLcall("glDisable(GL_TEXTURE_GEN_S,T,R)");
3281 case D3DTSS_TCI_CAMERASPACEPOSITION
:
3282 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3283 as the input texture coordinates for this stage's texture transformation. This
3284 equates roughly to EYE_LINEAR */
3286 float s_plane
[] = { 1.0, 0.0, 0.0, 0.0 };
3287 float t_plane
[] = { 0.0, 1.0, 0.0, 0.0 };
3288 float r_plane
[] = { 0.0, 0.0, 1.0, 0.0 };
3289 float q_plane
[] = { 0.0, 0.0, 0.0, 1.0 };
3290 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
3292 glMatrixMode(GL_MODELVIEW
);
3295 glTexGenfv(GL_S
, GL_EYE_PLANE
, s_plane
);
3296 glTexGenfv(GL_T
, GL_EYE_PLANE
, t_plane
);
3297 glTexGenfv(GL_R
, GL_EYE_PLANE
, r_plane
);
3298 glTexGenfv(GL_Q
, GL_EYE_PLANE
, q_plane
);
3301 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
3302 glEnable(GL_TEXTURE_GEN_S
);
3303 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
3304 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_EYE_LINEAR
);
3305 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
3306 glEnable(GL_TEXTURE_GEN_T
);
3307 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
3308 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_EYE_LINEAR
);
3309 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
3310 glEnable(GL_TEXTURE_GEN_R
);
3311 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
3312 glTexGeni(GL_R
, GL_TEXTURE_GEN_MODE
, GL_EYE_LINEAR
);
3313 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
3317 case D3DTSS_TCI_CAMERASPACENORMAL
:
3319 if (GL_SUPPORT(NV_TEXGEN_REFLECTION
)) {
3320 float s_plane
[] = { 1.0, 0.0, 0.0, 0.0 };
3321 float t_plane
[] = { 0.0, 1.0, 0.0, 0.0 };
3322 float r_plane
[] = { 0.0, 0.0, 1.0, 0.0 };
3323 float q_plane
[] = { 0.0, 0.0, 0.0, 1.0 };
3324 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
3326 glMatrixMode(GL_MODELVIEW
);
3329 glTexGenfv(GL_S
, GL_EYE_PLANE
, s_plane
);
3330 glTexGenfv(GL_T
, GL_EYE_PLANE
, t_plane
);
3331 glTexGenfv(GL_R
, GL_EYE_PLANE
, r_plane
);
3332 glTexGenfv(GL_Q
, GL_EYE_PLANE
, q_plane
);
3335 glEnable(GL_TEXTURE_GEN_S
);
3336 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
3337 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_NORMAL_MAP_NV
);
3338 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
3339 glEnable(GL_TEXTURE_GEN_T
);
3340 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
3341 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_NORMAL_MAP_NV
);
3342 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
3343 glEnable(GL_TEXTURE_GEN_R
);
3344 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
3345 glTexGeni(GL_R
, GL_TEXTURE_GEN_MODE
, GL_NORMAL_MAP_NV
);
3346 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
3351 case D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR
:
3353 if (GL_SUPPORT(NV_TEXGEN_REFLECTION
)) {
3354 float s_plane
[] = { 1.0, 0.0, 0.0, 0.0 };
3355 float t_plane
[] = { 0.0, 1.0, 0.0, 0.0 };
3356 float r_plane
[] = { 0.0, 0.0, 1.0, 0.0 };
3357 float q_plane
[] = { 0.0, 0.0, 0.0, 1.0 };
3358 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
3360 glMatrixMode(GL_MODELVIEW
);
3363 glTexGenfv(GL_S
, GL_EYE_PLANE
, s_plane
);
3364 glTexGenfv(GL_T
, GL_EYE_PLANE
, t_plane
);
3365 glTexGenfv(GL_R
, GL_EYE_PLANE
, r_plane
);
3366 glTexGenfv(GL_Q
, GL_EYE_PLANE
, q_plane
);
3369 glEnable(GL_TEXTURE_GEN_S
);
3370 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
3371 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_REFLECTION_MAP_NV
);
3372 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
3373 glEnable(GL_TEXTURE_GEN_T
);
3374 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
3375 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_REFLECTION_MAP_NV
);
3376 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
3377 glEnable(GL_TEXTURE_GEN_R
);
3378 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
3379 glTexGeni(GL_R
, GL_TEXTURE_GEN_MODE
, GL_REFLECTION_MAP_NV
);
3380 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
3385 /* Unhandled types: */
3388 /* ? disable GL_TEXTURE_GEN_n ? */
3389 glDisable(GL_TEXTURE_GEN_S
);
3390 glDisable(GL_TEXTURE_GEN_T
);
3391 glDisable(GL_TEXTURE_GEN_R
);
3392 FIXME("Unhandled D3DTSS_TEXCOORDINDEX %lx\n", Value
);
3399 case D3DTSS_TEXTURETRANSFORMFLAGS
:
3400 set_texture_matrix((float *)&This
->stateBlock
->transforms
[D3DTS_TEXTURE0
+ Stage
].u
.m
[0][0], Value
);
3403 case D3DTSS_BUMPENVMAT00
:
3404 case D3DTSS_BUMPENVMAT01
:
3405 TRACE("BUMPENVMAT0%u Stage=%ld, Type=%d, Value =%ld\n", Type
- D3DTSS_BUMPENVMAT00
, Stage
, Type
, Value
);
3407 case D3DTSS_BUMPENVMAT10
:
3408 case D3DTSS_BUMPENVMAT11
:
3409 TRACE("BUMPENVMAT1%u Stage=%ld, Type=%d, Value =%ld\n", Type
- D3DTSS_BUMPENVMAT10
, Stage
, Type
, Value
);
3412 case D3DTSS_BUMPENVLSCALE
:
3413 TRACE("BUMPENVLSCALE Stage=%ld, Type=%d, Value =%ld\n", Stage
, Type
, Value
);
3416 case D3DTSS_BUMPENVLOFFSET
:
3417 TRACE("BUMPENVLOFFSET Stage=%ld, Type=%d, Value =%ld\n", Stage
, Type
, Value
);
3420 case D3DTSS_RESULTARG
:
3421 TRACE("RESULTARG Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage
, Type
, Value
);
3425 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
3426 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage
, Type
, Value
);
3434 HRESULT WINAPI
IWineD3DDeviceImpl_GetTextureStageState(IWineD3DDevice
*iface
, DWORD Stage
, D3DTEXTURESTAGESTATETYPE Type
, DWORD
* pValue
) {
3435 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
3436 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This
, Stage
, Type
, This
->updateStateBlock
->textureState
[Stage
][Type
]);
3437 *pValue
= This
->updateStateBlock
->textureState
[Stage
][Type
];
3444 HRESULT WINAPI
IWineD3DDeviceImpl_SetTexture(IWineD3DDevice
*iface
, DWORD Stage
, IWineD3DBaseTexture
* pTexture
) {
3446 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
3447 IWineD3DBaseTexture
*oldTexture
;
3448 BOOL reapplyStates
= TRUE
;
3449 DWORD reapplyFlags
= 0;
3450 INT oldTextureDimensions
= -1;
3451 D3DRESOURCETYPE textureType
;
3453 oldTexture
= This
->updateStateBlock
->textures
[Stage
];
3454 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This
, Stage
, pTexture
);
3456 /* Reject invalid texture units */
3457 if (Stage
>= GL_LIMITS(textures
)) {
3458 TRACE("Attempt to access invalid texture rejected\n");
3459 return D3DERR_INVALIDCALL
;
3462 This
->updateStateBlock
->set
.textures
[Stage
] = TRUE
;
3463 This
->updateStateBlock
->changed
.textures
[Stage
] = TRUE
;
3464 This
->updateStateBlock
->textures
[Stage
] = pTexture
;
3466 /* Handle recording of state blocks */
3467 if (This
->isRecordingState
) {
3468 TRACE("Recording... not performing anything\n");
3472 oldTextureDimensions
= This
->updateStateBlock
->textureDimensions
[Stage
];
3476 /* Make appropriate texture active */
3477 if (GL_SUPPORT(ARB_MULTITEXTURE
)) {
3478 GLACTIVETEXTURE(Stage
);
3480 } else if (Stage
>0) {
3481 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
3484 /** NOTE: MSDN says that setTexture increases the reference count,
3485 * and the the application nust set the texture back to null (or have a leaky application),
3486 * This means we should pass the refcount upto the parent
3487 *******************************/
3488 if (NULL
!= oldTexture
) {
3490 IUnknown
*textureParent
;
3491 IWineD3DBaseTexture_GetParent(oldTexture
, (IUnknown
**)&textureParent
);
3492 IUnknown_Release(textureParent
);
3493 IUnknown_Release(textureParent
); /** NOTE: Twice because GetParent adds a ref **/
3498 if (NULL
!= pTexture
) {
3499 IUnknown
*textureParent
;
3500 IWineD3DBaseTexture_GetParent(This
->updateStateBlock
->textures
[Stage
], (IUnknown
**)&textureParent
);
3501 /** NOTE: GetParent will increase the ref count for me, I won't clean up untill the texture is set to NULL **/
3503 /* Now setup the texture appropraitly */
3504 textureType
= IWineD3DBaseTexture_GetType(pTexture
);
3506 if (textureType
== D3DRTYPE_TEXTURE
) {
3508 if (oldTexture
== pTexture
&& !IWineD3DBaseTexture_GetDirty(pTexture
)) {
3509 TRACE("Skipping setting texture as old == new\n");
3510 reapplyStates
= FALSE
;
3514 /* Standard 2D texture */
3515 TRACE("Standard 2d texture\n");
3516 This
->updateStateBlock
->textureDimensions
[Stage
] = GL_TEXTURE_2D
;
3518 /* Load up the texture now */
3519 IWineD3DTexture_PreLoad((IWineD3DTexture
*) pTexture
);
3522 } else if (textureType
== D3DRTYPE_VOLUMETEXTURE
) {
3524 if (oldTexture
== pTexture
&& !IWineD3DBaseTexture_GetDirty(pTexture
)) {
3525 TRACE("Skipping setting texture as old == new\n");
3526 reapplyStates
= FALSE
;
3530 /* Standard 3D (volume) texture */
3531 TRACE("Standard 3d texture\n");
3532 This
->updateStateBlock
->textureDimensions
[Stage
] = GL_TEXTURE_3D
;
3534 /* Load up the texture now */
3535 IWineD3DVolumeTexture_PreLoad((IWineD3DVolumeTexture
*) pTexture
);
3538 } else if (textureType
== D3DRTYPE_CUBETEXTURE
) {
3540 if (oldTexture
== pTexture
&& !IWineD3DBaseTexture_GetDirty(pTexture
)) {
3541 TRACE("Skipping setting texture as old == new\n");
3542 reapplyStates
= FALSE
;
3546 /* Standard Cube texture */
3547 TRACE("Standard Cube texture\n");
3548 This
->updateStateBlock
->textureDimensions
[Stage
] = GL_TEXTURE_CUBE_MAP_ARB
;
3550 /* Load up the texture now */
3551 IWineD3DCubeTexture_PreLoad((IWineD3DCubeTexture
*) pTexture
);
3555 FIXME("(%p) : Incorrect type for a texture : (%d,%s)\n", This
, textureType
, debug_d3dresourcetype(textureType
));
3560 TRACE("Setting to no texture (ie default texture)\n");
3561 This
->updateStateBlock
->textureDimensions
[Stage
] = GL_TEXTURE_1D
;
3562 glBindTexture(GL_TEXTURE_1D
, This
->dummyTextureName
[Stage
]);
3563 checkGLcall("glBindTexture");
3564 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage
, This
->dummyTextureName
[Stage
]);
3567 /* Disable the old texture binding and enable the new one (unless operations are disabled) */
3568 if (oldTextureDimensions
!= This
->updateStateBlock
->textureDimensions
[Stage
]) {
3570 glDisable(oldTextureDimensions
);
3571 checkGLcall("Disable oldTextureDimensions");
3573 if (This
->stateBlock
->textureState
[Stage
][D3DTSS_COLOROP
] != D3DTOP_DISABLE
) {
3574 glEnable(This
->updateStateBlock
->textureDimensions
[Stage
]);
3575 checkGLcall("glEnable new texture dimensions");
3578 /* If Alpha arg1 is texture then handle the special case when there changes between a
3579 texture and no texture - See comments in set_tex_op */
3580 if ((This
->stateBlock
->textureState
[Stage
][D3DTSS_ALPHAARG1
] == D3DTA_TEXTURE
) &&
3581 (((oldTexture
== NULL
) && (pTexture
!= NULL
)) || ((pTexture
== NULL
) && (oldTexture
!= NULL
))))
3583 reapplyFlags
|= REAPPLY_ALPHAOP
;
3588 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
3589 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
3590 if (reapplyStates
) {
3591 IWineD3DDeviceImpl_SetupTextureStates(iface
, Stage
, reapplyFlags
);
3595 TRACE("Texture now fully setup\n");
3600 HRESULT WINAPI
IWineD3DDeviceImpl_GetTexture(IWineD3DDevice
*iface
, DWORD Stage
, IWineD3DBaseTexture
** ppTexture
) {
3601 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
3602 TRACE("(%p) : returning %p for stage %ld\n", This
, This
->updateStateBlock
->textures
[Stage
], Stage
);
3603 *ppTexture
= (IWineD3DBaseTexture
*) This
->updateStateBlock
->textures
[Stage
];
3605 IWineD3DBaseTexture_AddRef(*ppTexture
);
3612 HRESULT WINAPI
IWineD3DDeviceImpl_GetBackBuffer(IWineD3DDevice
*iface
, UINT iSwapChain
, UINT BackBuffer
, D3DBACKBUFFER_TYPE Type
,
3613 IWineD3DSurface
** ppBackBuffer
) {
3614 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
3616 *ppBackBuffer
= (IWineD3DSurface
*) This
->backBuffer
;
3617 TRACE("(%p) : BackBuf %d Type %d SwapChain %d returning %p\n", This
, BackBuffer
, Type
, iSwapChain
, *ppBackBuffer
);
3619 if (BackBuffer
> This
->presentParms
.BackBufferCount
- 1) {
3620 FIXME("Only one backBuffer currently supported\n");
3621 return D3DERR_INVALIDCALL
;
3624 /* Note inc ref on returned surface */
3625 IWineD3DSurface_AddRef(*ppBackBuffer
);
3630 HRESULT WINAPI
IWineD3DDeviceImpl_GetDeviceCaps(IWineD3DDevice
*iface
, D3DCAPS9
* pCaps
) {
3631 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
3632 WARN("(%p) : stub, calling idirect3d for now\n", This
);
3633 IWineD3D_GetDeviceCaps(This
->wineD3D
, This
->adapterNo
, This
->devType
, pCaps
);
3637 /** TODO: move to swapchains **/
3638 HRESULT WINAPI
IWineD3DDeviceImpl_GetDisplayMode(IWineD3DDevice
*iface
, UINT iSwapChain
, D3DDISPLAYMODE
* pMode
) {
3639 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
3643 pMode
->Width
= GetSystemMetrics(SM_CXSCREEN
);
3644 pMode
->Height
= GetSystemMetrics(SM_CYSCREEN
);
3645 pMode
->RefreshRate
= 85; /*FIXME: How to identify? */
3647 hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
3648 bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
3652 case 8: pMode
->Format
= WINED3DFMT_R8G8B8
; break;
3653 case 16: pMode
->Format
= WINED3DFMT_R5G6B5
; break;
3654 case 24: /*pMode->Format = WINED3DFMT_R8G8B8; break; */
3655 case 32: pMode
->Format
= WINED3DFMT_A8R8G8B8
; break;
3657 FIXME("Unrecognized display mode format\n");
3658 pMode
->Format
= WINED3DFMT_UNKNOWN
;
3661 FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This
, pMode
->Width
, pMode
->Height
, pMode
->RefreshRate
,
3662 pMode
->Format
, debug_d3dformat(pMode
->Format
));
3666 * Stateblock related functions
3669 HRESULT WINAPI
IWineD3DDeviceImpl_BeginStateBlock(IWineD3DDevice
*iface
) {
3670 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
3671 IWineD3DStateBlockImpl
*object
;
3672 TRACE("(%p)", This
);
3673 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IWineD3DStateBlockImpl
));
3674 if(NULL
== object
){
3675 FIXME("(%p)Error allocating memory for stateblock\n", This
);
3676 return E_OUTOFMEMORY
;
3678 TRACE("(%p) creted object %p\n", This
, object
);
3679 object
->wineD3DDevice
= This
;
3680 /** FIXME: object->parent = parent; **/
3681 object
->parent
= NULL
;
3682 object
->blockType
= D3DSBT_ALL
;
3684 object
->lpVtbl
= &IWineD3DStateBlock_Vtbl
;
3686 IWineD3DStateBlock_Release((IWineD3DStateBlock
*)This
->updateStateBlock
);
3687 This
->updateStateBlock
= object
;
3688 This
->isRecordingState
= TRUE
;
3690 TRACE("(%p) recording stateblock %p\n",This
, object
);
3694 HRESULT WINAPI
IWineD3DDeviceImpl_EndStateBlock(IWineD3DDevice
*iface
, IWineD3DStateBlock
** ppStateBlock
) {
3695 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
3697 if (!This
->isRecordingState
) {
3698 FIXME("(%p) not recording! returning error\n", This
);
3699 *ppStateBlock
= NULL
;
3700 return D3DERR_INVALIDCALL
;
3703 *ppStateBlock
= (IWineD3DStateBlock
*)This
->updateStateBlock
;
3704 This
->isRecordingState
= FALSE
;
3705 This
->updateStateBlock
= This
->stateBlock
;
3706 IWineD3DStateBlock_AddRef((IWineD3DStateBlock
*)This
->updateStateBlock
);
3707 /* IWineD3DStateBlock_AddRef(*ppStateBlock); don't need to do this, since we should really just release UpdateStateBlock first */
3708 TRACE("(%p) returning token (ptr to stateblock) of %p\n", This
, *ppStateBlock
);
3713 * Scene related functions
3715 HRESULT WINAPI
IWineD3DDeviceImpl_BeginScene(IWineD3DDevice
*iface
) {
3716 /* At the moment we have no need for any functionality at the beginning
3718 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
3719 TRACE("(%p) : stub\n", This
);
3723 HRESULT WINAPI
IWineD3DDeviceImpl_EndScene(IWineD3DDevice
*iface
) {
3724 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
3725 TRACE("(%p)\n", This
);
3727 /* We only have to do this if we need to read the, swapbuffers performs a flush for us */
3729 checkGLcall("glFlush");
3731 TRACE("End Scene\n");
3732 if(This
->renderTarget
!= NULL
){
3734 /* If the container of the rendertarget is a texture then we need to save the data from the pbuffer */
3735 IUnknown
*targetContainer
= NULL
;
3736 if (D3D_OK
== IWineD3DSurface_GetContainer(This
->renderTarget
, &IID_IWineD3DBaseTexture
, (void **)&targetContainer
)) {
3737 TRACE("RenderTarget is either standalone of a texture.\n");
3738 /** always dirtify for now. we must find a better way to see that surface have been modified
3739 (Modifications should will only occur via draw-primitive, but we do need better locking
3740 switching to render-to-texture should remove the overhead though.
3742 IWineD3DSurface_SetPBufferState(This
->renderTarget
, TRUE
/* inPBuffer */, FALSE
/* inTexture */);
3743 IWineD3DBaseTexture_SetDirty((IWineD3DBaseTexture
*)targetContainer
, TRUE
);
3744 IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture
*)targetContainer
);
3745 IWineD3DSurface_SetPBufferState(This
->renderTarget
, FALSE
/* inPBuffer */, FALSE
/* inTexture */);
3746 IUnknown_Release(targetContainer
);
3755 HRESULT WINAPI
IWineD3DDeviceImpl_Present(IWineD3DDevice
*iface
,
3756 CONST RECT
* pSourceRect
, CONST RECT
* pDestRect
,
3757 HWND hDestWindowOverride
, CONST RGNDATA
* pDirtyRegion
) {
3758 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
3759 TRACE("(%p) Presenting the frame\n", This
);
3763 if (pSourceRect
|| pDestRect
) FIXME("Unhandled present options %p/%p\n", pSourceRect
, pDestRect
);
3765 glXSwapBuffers(This
->display
, This
->drawable
);
3766 /* Don't call checkGLcall, as glGetError is not applicable here */
3768 TRACE("glXSwapBuffers called, Starting new frame\n");
3771 if (TRACE_ON(d3d_fps
))
3773 static long prev_time
, frames
;
3775 DWORD time
= GetTickCount();
3777 /* every 1.5 seconds */
3778 if (time
- prev_time
> 1500) {
3779 TRACE_(d3d_fps
)("@ approx %.2ffps\n", 1000.0*frames
/(time
- prev_time
));
3785 #if defined(FRAME_DEBUGGING)
3787 if (GetFileAttributesA("C:\\D3DTRACE") != INVALID_FILE_ATTRIBUTES
) {
3790 FIXME("Enabling D3D Trace\n");
3791 __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE
, __wine_dbch_d3d
, 1);
3792 #if defined(SHOW_FRAME_MAKEUP)
3793 FIXME("Singe Frame snapshots Starting\n");
3794 isDumpingFrames
= TRUE
;
3795 glClear(GL_COLOR_BUFFER_BIT
);
3798 #if defined(SINGLE_FRAME_DEBUGGING)
3800 #if defined(SHOW_FRAME_MAKEUP)
3801 FIXME("Singe Frame snapshots Finishing\n");
3802 isDumpingFrames
= FALSE
;
3804 FIXME("Singe Frame trace complete\n");
3805 DeleteFileA("C:\\D3DTRACE");
3806 __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE
, __wine_dbch_d3d
, 0);
3812 #if defined(SHOW_FRAME_MAKEUP)
3813 FIXME("Singe Frame snapshots Finishing\n");
3814 isDumpingFrames
= FALSE
;
3816 FIXME("Disabling D3D Trace\n");
3817 __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE
, __wine_dbch_d3d
, 0);
3824 /* Although this is not strictly required, a simple demo showed this does occur
3825 on (at least non-debug) d3d */
3826 if (This
->presentParms
.SwapEffect
== D3DSWAPEFFECT_DISCARD
) {
3827 IWineD3DDevice_Clear(iface
, 0, NULL
, D3DCLEAR_STENCIL
|D3DCLEAR_ZBUFFER
|D3DCLEAR_TARGET
, 0x00, 1.0, 0);
3833 HRESULT WINAPI
IWineD3DDeviceImpl_Clear(IWineD3DDevice
*iface
, DWORD Count
, CONST D3DRECT
* pRects
,
3834 DWORD Flags
, D3DCOLOR Color
, float Z
, DWORD Stencil
) {
3835 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
3837 /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
3838 render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
3839 when the depth-buffer format does not contain stencil buffer information, this method fails. */
3840 GLbitfield glMask
= 0;
3841 GLboolean old_ztest
;
3842 GLfloat old_z_clear_value
;
3843 GLint old_stencil_clear_value
;
3844 GLfloat old_color_clear_value
[4];
3846 CONST D3DRECT
* curRect
;
3848 TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This
,
3849 Count
, pRects
, Flags
, Z
, Stencil
);
3853 glEnable(GL_SCISSOR_TEST
);
3854 checkGLcall("glEnable GL_SCISSOR_TEST");
3856 if (Count
> 0 && pRects
) {
3862 /* Only set the values up once, as they are not changing */
3863 if (Flags
& D3DCLEAR_STENCIL
) {
3864 glGetIntegerv(GL_STENCIL_CLEAR_VALUE
, &old_stencil_clear_value
);
3865 glClearStencil(Stencil
);
3866 checkGLcall("glClearStencil");
3867 glMask
= glMask
| GL_STENCIL_BUFFER_BIT
;
3868 glStencilMask(0xFFFFFFFF);
3871 if (Flags
& D3DCLEAR_ZBUFFER
) {
3872 glGetBooleanv(GL_DEPTH_WRITEMASK
, &old_ztest
);
3873 glDepthMask(GL_TRUE
);
3874 glGetFloatv(GL_DEPTH_CLEAR_VALUE
, &old_z_clear_value
);
3876 checkGLcall("glClearDepth");
3877 glMask
= glMask
| GL_DEPTH_BUFFER_BIT
;
3880 if (Flags
& D3DCLEAR_TARGET
) {
3881 TRACE("Clearing screen with glClear to color %lx\n", Color
);
3882 glGetFloatv(GL_COLOR_CLEAR_VALUE
, old_color_clear_value
);
3883 glClearColor(((Color
>> 16) & 0xFF) / 255.0f
,
3884 ((Color
>> 8) & 0xFF) / 255.0f
,
3885 ((Color
>> 0) & 0xFF) / 255.0f
,
3886 ((Color
>> 24) & 0xFF) / 255.0f
);
3887 checkGLcall("glClearColor");
3889 /* Clear ALL colors! */
3890 glColorMask(GL_TRUE
, GL_TRUE
, GL_TRUE
, GL_TRUE
);
3891 glMask
= glMask
| GL_COLOR_BUFFER_BIT
;
3894 /* Now process each rect in turn */
3895 for (i
= 0; i
< Count
|| i
== 0; i
++) {
3898 /* Note gl uses lower left, width/height */
3899 TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This
, curRect
,
3900 curRect
->x1
, curRect
->y1
, curRect
->x2
, curRect
->y2
,
3901 curRect
->x1
, (((IWineD3DSurfaceImpl
*)This
->renderTarget
)->currentDesc
.Height
- curRect
->y2
),
3902 curRect
->x2
- curRect
->x1
, curRect
->y2
- curRect
->y1
);
3903 glScissor(curRect
->x1
, (((IWineD3DSurfaceImpl
*)This
->renderTarget
)->currentDesc
.Height
- curRect
->y2
),
3904 curRect
->x2
- curRect
->x1
, curRect
->y2
- curRect
->y1
);
3905 checkGLcall("glScissor");
3907 glScissor(This
->stateBlock
->viewport
.X
,
3908 (((IWineD3DSurfaceImpl
*)This
->renderTarget
)->currentDesc
.Height
- (This
->stateBlock
->viewport
.Y
+ This
->stateBlock
->viewport
.Height
)),
3909 This
->stateBlock
->viewport
.Width
,
3910 This
->stateBlock
->viewport
.Height
);
3911 checkGLcall("glScissor");
3914 /* Clear the selected rectangle (or full screen) */
3916 checkGLcall("glClear");
3918 /* Step to the next rectangle */
3919 if (curRect
) curRect
= curRect
+ sizeof(D3DRECT
);
3922 /* Restore the old values (why..?) */
3923 if (Flags
& D3DCLEAR_STENCIL
) {
3924 glClearStencil(old_stencil_clear_value
);
3925 glStencilMask(This
->stateBlock
->renderState
[WINED3DRS_STENCILWRITEMASK
]);
3927 if (Flags
& D3DCLEAR_ZBUFFER
) {
3928 glDepthMask(old_ztest
);
3929 glClearDepth(old_z_clear_value
);
3931 if (Flags
& D3DCLEAR_TARGET
) {
3932 glClearColor(old_color_clear_value
[0],
3933 old_color_clear_value
[1],
3934 old_color_clear_value
[2],
3935 old_color_clear_value
[3]);
3936 glColorMask(This
->stateBlock
->renderState
[WINED3DRS_COLORWRITEENABLE
] & D3DCOLORWRITEENABLE_RED
? GL_TRUE
: GL_FALSE
,
3937 This
->stateBlock
->renderState
[WINED3DRS_COLORWRITEENABLE
] & D3DCOLORWRITEENABLE_GREEN
? GL_TRUE
: GL_FALSE
,
3938 This
->stateBlock
->renderState
[WINED3DRS_COLORWRITEENABLE
] & D3DCOLORWRITEENABLE_BLUE
? GL_TRUE
: GL_FALSE
,
3939 This
->stateBlock
->renderState
[WINED3DRS_COLORWRITEENABLE
] & D3DCOLORWRITEENABLE_ALPHA
? GL_TRUE
: GL_FALSE
);
3942 glDisable(GL_SCISSOR_TEST
);
3943 checkGLcall("glDisable");
3952 HRESULT WINAPI
IWineD3DDeviceImpl_DrawPrimitive(IWineD3DDevice
*iface
, D3DPRIMITIVETYPE PrimitiveType
, UINT StartVertex
,
3953 UINT PrimitiveCount
) {
3955 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
3956 This
->stateBlock
->streamIsUP
= FALSE
;
3958 TRACE("(%p) : Type=(%d,%s), Start=%d, Count=%d\n", This
, PrimitiveType
,
3959 debug_d3dprimitivetype(PrimitiveType
),
3960 StartVertex
, PrimitiveCount
);
3961 drawPrimitive(iface
, PrimitiveType
, PrimitiveCount
, StartVertex
, -1, 0, NULL
, 0);
3966 /* TODO: baseVIndex needs to be provided from This->stateBlock->baseVertexIndex when called from d3d8 */
3967 HRESULT WINAPI
IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice
*iface
,
3968 D3DPRIMITIVETYPE PrimitiveType
,
3969 INT baseVIndex
, UINT minIndex
,
3970 UINT NumVertices
,UINT startIndex
,UINT primCount
) {
3972 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
3974 IWineD3DIndexBuffer
*pIB
;
3975 D3DINDEXBUFFER_DESC IdxBufDsc
;
3977 pIB
= This
->stateBlock
->pIndexData
;
3978 This
->stateBlock
->streamIsUP
= FALSE
;
3980 TRACE("(%p) : Type=(%d,%s), min=%d, CountV=%d, startIdx=%d, baseVidx=%d, countP=%d \n", This
,
3981 PrimitiveType
, debug_d3dprimitivetype(PrimitiveType
),
3982 minIndex
, NumVertices
, startIndex
, baseVIndex
, primCount
);
3984 IWineD3DIndexBuffer_GetDesc(pIB
, &IdxBufDsc
);
3985 if (IdxBufDsc
.Format
== WINED3DFMT_INDEX16
) {
3991 drawPrimitive(iface
, PrimitiveType
, primCount
, baseVIndex
,
3992 startIndex
, idxStride
,
3993 ((IWineD3DIndexBufferImpl
*) pIB
)->resource
.allocatedMemory
,
3999 HRESULT WINAPI
IWineD3DDeviceImpl_DrawPrimitiveUP(IWineD3DDevice
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4000 UINT PrimitiveCount
, CONST
void* pVertexStreamZeroData
,
4001 UINT VertexStreamZeroStride
) {
4002 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4004 TRACE("(%p) : Type=(%d,%s), pCount=%d, pVtxData=%p, Stride=%d\n", This
, PrimitiveType
,
4005 debug_d3dprimitivetype(PrimitiveType
),
4006 PrimitiveCount
, pVertexStreamZeroData
, VertexStreamZeroStride
);
4008 if (This
->stateBlock
->stream_source
[0] != NULL
) IWineD3DVertexBuffer_Release(This
->stateBlock
->stream_source
[0]);
4010 /* Note in the following, it's not this type, but that's the purpose of streamIsUP */
4011 This
->stateBlock
->stream_source
[0] = (IWineD3DVertexBuffer
*)pVertexStreamZeroData
;
4012 This
->stateBlock
->stream_stride
[0] = VertexStreamZeroStride
;
4013 This
->stateBlock
->streamIsUP
= TRUE
;
4014 drawPrimitive(iface
, PrimitiveType
, PrimitiveCount
, 0, 0, 0, NULL
, 0);
4015 This
->stateBlock
->stream_stride
[0] = 0;
4016 This
->stateBlock
->stream_source
[0] = NULL
;
4018 /*stream zero settings set to null at end, as per the msdn */
4022 HRESULT WINAPI
IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4023 UINT MinVertexIndex
,
4024 UINT NumVertexIndices
,UINT PrimitiveCount
,CONST
void* pIndexData
,
4025 WINED3DFORMAT IndexDataFormat
, CONST
void* pVertexStreamZeroData
,
4026 UINT VertexStreamZeroStride
) {
4028 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4030 TRACE("(%p) : Type=(%d,%s), MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n",
4031 This
, PrimitiveType
, debug_d3dprimitivetype(PrimitiveType
),
4032 MinVertexIndex
, NumVertexIndices
, PrimitiveCount
, pIndexData
,
4033 IndexDataFormat
, pVertexStreamZeroData
, VertexStreamZeroStride
);
4035 if (This
->stateBlock
->stream_source
[0] != NULL
) IWineD3DVertexBuffer_Release(This
->stateBlock
->stream_source
[0]);
4037 if (IndexDataFormat
== WINED3DFMT_INDEX16
) {
4043 /* Note in the following, it's not this type, but that's the purpose of streamIsUP */
4044 This
->stateBlock
->stream_source
[0] = (IWineD3DVertexBuffer
*)pVertexStreamZeroData
;
4045 This
->stateBlock
->streamIsUP
= TRUE
;
4046 This
->stateBlock
->stream_stride
[0] = VertexStreamZeroStride
;
4048 drawPrimitive(iface
, PrimitiveType
, PrimitiveCount
, 0, 0, idxStride
, pIndexData
, MinVertexIndex
);
4050 /* stream zero settings set to null at end as per the msdn */
4051 This
->stateBlock
->stream_source
[0] = NULL
;
4052 This
->stateBlock
->stream_stride
[0] = 0;
4053 IWineD3DDevice_SetIndices(iface
, NULL
, 0);
4058 HRESULT WINAPI
IWineD3DDeviceImpl_UpdateTexture (IWineD3DDevice
*iface
, IWineD3DBaseTexture
*pSourceTexture
, IWineD3DBaseTexture
*pDestinationTexture
){
4059 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4061 TRACE("(%p) : stub\n", This
);
4065 HRESULT WINAPI
IWineD3DDeviceImpl_StretchRect(IWineD3DDevice
*iface
, IWineD3DSurface
*pSourceSurface
,
4066 CONST RECT
* pSourceRect
, IWineD3DSurface
*pDestinationSurface
,
4067 CONST RECT
* pDestRect
, D3DTEXTUREFILTERTYPE Filter
) {
4068 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4070 TRACE("(%p) : stub\n", This
);
4073 HRESULT WINAPI
IWineD3DDeviceImpl_GetRenderTargetData(IWineD3DDevice
*iface
, IWineD3DSurface
*pRenderTarget
, IWineD3DSurface
*pSurface
){
4074 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4076 TRACE("(%p) : stub\n", This
);
4080 HRESULT WINAPI
IWineD3DDeviceImpl_GetFrontBufferData(IWineD3DDevice
*iface
,UINT iSwapChain
, IWineD3DSurface
*pDestSurface
){
4081 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4083 TRACE("(%p) : stub\n", This
);
4087 HRESULT WINAPI
IWineD3DDeviceImpl_ValidateDevice(IWineD3DDevice
*iface
, DWORD
* pNumPasses
) {
4088 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4089 /* return a sensible default */
4091 FIXME("(%p) : stub\n", This
);
4095 HRESULT WINAPI
IWineD3DDeviceImpl_SetPaletteEntries(IWineD3DDevice
*iface
, UINT PaletteNumber
, CONST PALETTEENTRY
* pEntries
) {
4096 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4097 FIXME("(%p) : stub\n", This
);
4101 HRESULT WINAPI
IWineD3DDeviceImpl_GetPaletteEntries(IWineD3DDevice
*iface
, UINT PaletteNumber
, PALETTEENTRY
* pEntries
) {
4102 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4103 FIXME("(%p) : stub\n", This
);
4107 HRESULT WINAPI
IWineD3DDeviceImpl_SetCurrentTexturePalette(IWineD3DDevice
*iface
, UINT PaletteNumber
) {
4108 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4109 FIXME("(%p) : stub\n", This
);
4113 HRESULT WINAPI
IWineD3DDeviceImpl_GetCurrentTexturePalette(IWineD3DDevice
*iface
, UINT
* PaletteNumber
) {
4114 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4115 FIXME("(%p) : stub\n", This
);
4119 HRESULT WINAPI
IWineD3DDeviceImpl_SetSoftwareVertexProcessing(IWineD3DDevice
*iface
, BOOL bSoftware
) {
4120 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4121 FIXME("(%p) : stub\n", This
);
4126 BOOL WINAPI
IWineD3DDeviceImpl_GetSoftwareVertexProcessing(IWineD3DDevice
*iface
) {
4127 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4128 FIXME("(%p) : stub\n", This
);
4133 HRESULT WINAPI
IWineD3DDeviceImpl_GetRasterStatus(IWineD3DDevice
*iface
, UINT iSwapChain
, D3DRASTER_STATUS
* pRasterStatus
) {
4134 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4136 pRasterStatus
->InVBlank
= TRUE
;
4137 pRasterStatus
->ScanLine
= 0;
4138 FIXME("(%p) : stub\n", This
);
4143 HRESULT WINAPI
IWineD3DDeviceImpl_SetNPatchMode(IWineD3DDevice
*iface
, float nSegments
) {
4144 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4145 static BOOL showfixmes
= TRUE
;
4146 if(nSegments
!= 0.0f
){
4148 FIXME("(%p) : stub nSegments(%f)\n", This
, nSegments
);
4155 float WINAPI
IWineD3DDeviceImpl_GetNPatchMode(IWineD3DDevice
*iface
) {
4156 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4157 static BOOL showfixmes
= TRUE
;
4159 FIXME("(%p) : stub returning(%f)\n", This
, 0.0f
);
4166 HRESULT WINAPI
IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice
*iface
, IWineD3DSurface
*pSourceSurface
, CONST RECT
* pSourceRect
, IWineD3DSurface
*pDestinationSurface
, CONST POINT
* pDestPoint
) {
4167 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*) iface
;
4168 FIXME("(%p) : stub\n", This
);
4173 /* Implementation details at http://developer.nvidia.com/attach/6494
4175 http://oss.sgi.com/projects/ogl-sample/registry/NV/evaluators.txt
4176 hmm.. no longer supported use
4177 OpenGL evaluators or tessellate surfaces within your application.
4180 /* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/d3d/interfaces/idirect3ddevice9/DrawRectPatch.asp */
4181 HRESULT WINAPI
IWineD3DDeviceImpl_DrawRectPatch(IWineD3DDevice
*iface
, UINT Handle
, CONST
float* pNumSegs
, CONST D3DRECTPATCH_INFO
* pRectPatchInfo
){
4182 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4183 TRACE("(%p) Handle(%d) noSegs(%p) rectpatch(%p) \n", This
, Handle
, pNumSegs
, pRectPatchInfo
);
4184 FIXME("(%p) : Stub\n", This
);
4189 /* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/d3d/interfaces/idirect3ddevice9/DrawTriPatch.asp */
4190 HRESULT WINAPI
IWineD3DDeviceImpl_DrawTriPatch(IWineD3DDevice
*iface
, UINT Handle
, CONST
float* pNumSegs
, CONST D3DTRIPATCH_INFO
* pTriPatchInfo
){
4191 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4192 TRACE("(%p) Handle(%d) noSegs(%p) tripatch(%p) \n", This
, Handle
, pNumSegs
, pTriPatchInfo
);
4193 FIXME("(%p) : Stub\n", This
);
4197 HRESULT WINAPI
IWineD3DDeviceImpl_DeletePatch(IWineD3DDevice
*iface
, UINT Handle
){
4198 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4199 TRACE("(%p) Handle(%d)\n", This
, Handle
);
4200 FIXME("(%p) : Stub\n", This
);
4204 HRESULT WINAPI
IWineD3DDeviceImpl_ColorFill(IWineD3DDevice
*iface
, IWineD3DSurface
*pSurface
, CONST D3DRECT
* pRect
, D3DCOLOR color
){
4205 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*) iface
;
4207 FIXME("(%p) : stub\n", This
);
4211 /* rendertarget and deptth stencil functions */
4212 HRESULT WINAPI
IWineD3DDeviceImpl_GetRenderTarget(IWineD3DDevice
* iface
,DWORD RenderTargetIndex
, IWineD3DSurface
**ppRenderTarget
){
4213 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4215 /* FIXME: Implelent RenderTargetIndex >0 */
4216 if(RenderTargetIndex
> 0)
4217 FIXME("(%p) : RenderTargetIndex %ld >0 not currently supported\n", This
, RenderTargetIndex
);
4219 *ppRenderTarget
= (IWineD3DSurface
*)This
->renderTarget
;
4220 TRACE("(%p) : RenderTarget %ld Index returning %p\n", This
, RenderTargetIndex
, *ppRenderTarget
);
4221 /* Note inc ref on returned surface */
4222 if(*ppRenderTarget
!= NULL
)
4223 IWineD3DSurface_AddRef(*ppRenderTarget
);
4227 HRESULT WINAPI
IWineD3DDeviceImpl_GetDepthStencilSurface(IWineD3DDevice
* iface
, IWineD3DSurface
**ppZStencilSurface
){
4228 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4229 *ppZStencilSurface
= (IWineD3DSurface
*)This
->depthStencilBuffer
;
4230 TRACE("(%p) : zStencilSurface returning %p\n", This
, *ppZStencilSurface
);
4232 if(*ppZStencilSurface
!= NULL
){
4233 /* Note inc ref on returned surface */
4234 IWineD3DSurface_AddRef(*ppZStencilSurface
);
4239 HRESULT WINAPI
IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice
*iface
, DWORD RenderTargetIndex
, IWineD3DSurface
*pRenderTarget
){
4240 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*) iface
;
4242 FIXME("(%p) : stub\n", This
);
4246 HRESULT WINAPI
IWineD3DDeviceImpl_SetDepthStencilSurface(IWineD3DDevice
*iface
, IWineD3DSurface
*pNewZStencil
){
4247 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*) iface
;
4249 FIXME("(%p) : stub\n", This
);
4253 HRESULT WINAPI
IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice
* iface
, UINT XHotSpot
,
4254 UINT YHotSpot
, IWineD3DSurface
*pCursorBitmap
) {
4255 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*) iface
;
4256 /* TODO: the use of Impl is deprecated. */
4257 /* some basic validation checks */
4258 IWineD3DSurfaceImpl
* pSur
= (IWineD3DSurfaceImpl
*) pCursorBitmap
;
4260 TRACE("(%p) : Spot Pos(%u,%u)\n", This
, XHotSpot
, YHotSpot
);
4262 if (WINED3DFMT_A8R8G8B8
!= pSur
->resource
.format
) {
4263 ERR("(%p) : surface(%p) has an invalid format\n", This
, pCursorBitmap
);
4264 return D3DERR_INVALIDCALL
;
4266 if (32 != pSur
->currentDesc
.Height
|| 32 != pSur
->currentDesc
.Width
) {
4267 ERR("(%p) : surface(%p) has an invalid size\n", This
, pCursorBitmap
);
4268 return D3DERR_INVALIDCALL
;
4270 /* TODO: make the cursor 'real' */
4272 This
->xHotSpot
= XHotSpot
;
4273 This
->yHotSpot
= YHotSpot
;
4278 void WINAPI
IWineD3DDeviceImpl_SetCursorPosition(IWineD3DDevice
* iface
, int XScreenSpace
, int YScreenSpace
, DWORD Flags
) {
4279 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*) iface
;
4280 TRACE("(%p) : SetPos to (%u,%u)\n", This
, XScreenSpace
, YScreenSpace
);
4282 This
->xScreenSpace
= XScreenSpace
;
4283 This
->yScreenSpace
= YScreenSpace
;
4289 BOOL WINAPI
IWineD3DDeviceImpl_ShowCursor(IWineD3DDevice
* iface
, BOOL bShow
) {
4290 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*) iface
;
4291 TRACE("(%p) : visible(%d)\n", This
, bShow
);
4293 This
->bCursorVisible
= bShow
;
4298 HRESULT WINAPI
IWineD3DDeviceImpl_TestCooperativeLevel(IWineD3DDevice
* iface
) {
4299 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*) iface
;
4300 FIXME("(%p) : stub\n", This
); /* No way of notifying yet! */
4305 HRESULT WINAPI
IWineD3DDeviceImpl_EvictManagedResources(IWineD3DDevice
* iface
) {
4306 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*) iface
;
4307 /** FIXME: Resource tracking needs to be done,
4308 * The closes we can do to this is set the priorities of all managed textures low
4309 * and then reset them.
4310 ***********************************************************/
4311 FIXME("(%p) : stub\n", This
);
4315 HRESULT WINAPI
IWineD3DDeviceImpl_Rest(IWineD3DDevice
* iface
, D3DPRESENT_PARAMETERS
* pPresentationParameters
) {
4316 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*) iface
;
4317 /** FIXME: Resource trascking needs to be done.
4318 * in effect this pulls all non only default
4319 * textures out of video memory and deletes all glTextures (glDeleteTextures)
4320 * and should clear down the context and set it up according to pPresentationParameters
4321 ***********************************************************/
4322 FIXME("(%p) : stub\n", This
);
4326 HRESULT WINAPI
IWineD3DDeviceImpl_SetDialogBoxMode(IWineD3DDevice
*iface
, BOOL bEnableDialogs
){
4327 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*)iface
;
4328 /** FIXME: always true at the moment **/
4329 if(bEnableDialogs
== FALSE
){
4330 FIXME("(%p) Dialogs cannot be disabled yet\n", This
);
4336 HRESULT WINAPI
IWineD3DDeviceImpl_GetCreationParameters(IWineD3DDevice
*iface
, D3DDEVICE_CREATION_PARAMETERS
*pParameters
) {
4337 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*) iface
;
4339 FIXME("(%p) : stub\n", This
);
4340 /* Setup some reasonable defaults */
4341 pParameters
->AdapterOrdinal
= 0; /* always for now */
4342 pParameters
->DeviceType
= D3DDEVTYPE_HAL
; /* always for now */
4343 pParameters
->hFocusWindow
= 0;
4344 pParameters
->BehaviorFlags
=0;
4348 void WINAPI
IWineD3DDeviceImpl_SetGammaRamp(IWineD3DDevice
* iface
, UINT iSwapChain
, DWORD Flags
, CONST D3DGAMMARAMP
* pRamp
) {
4350 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*) iface
;
4352 FIXME("(%p) : pRamp@%p\n", This
, pRamp
);
4353 hDC
= GetDC(This
->win_handle
);
4354 SetDeviceGammaRamp(hDC
, (LPVOID
) pRamp
);
4355 ReleaseDC(This
->win_handle
, hDC
);
4359 void WINAPI
IWineD3DDeviceImpl_GetGammaRamp(IWineD3DDevice
*iface
, UINT iSwapChain
, D3DGAMMARAMP
* pRamp
) {
4361 IWineD3DDeviceImpl
*This
= (IWineD3DDeviceImpl
*) iface
;
4363 FIXME("(%p) : pRamp@%p\n", This
, pRamp
);
4364 hDC
= GetDC(This
->win_handle
);
4365 GetDeviceGammaRamp(hDC
, pRamp
);
4366 ReleaseDC(This
->win_handle
, hDC
);
4370 /**********************************************************
4371 * IWineD3DDevice VTbl follows
4372 **********************************************************/
4374 IWineD3DDeviceVtbl IWineD3DDevice_Vtbl
=
4376 /*** IUnknown methods ***/
4377 IWineD3DDeviceImpl_QueryInterface
,
4378 IWineD3DDeviceImpl_AddRef
,
4379 IWineD3DDeviceImpl_Release
,
4380 /*** IWineD3DDevice methods ***/
4381 IWineD3DDeviceImpl_GetParent
,
4382 /*** Creation methods**/
4383 IWineD3DDeviceImpl_CreateVertexBuffer
,
4384 IWineD3DDeviceImpl_CreateIndexBuffer
,
4385 IWineD3DDeviceImpl_CreateStateBlock
,
4386 IWineD3DDeviceImpl_CreateSurface
,
4387 IWineD3DDeviceImpl_CreateTexture
,
4388 IWineD3DDeviceImpl_CreateVolumeTexture
,
4389 IWineD3DDeviceImpl_CreateVolume
,
4390 IWineD3DDeviceImpl_CreateCubeTexture
,
4391 IWineD3DDeviceImpl_CreateQuery
,
4392 IWineD3DDeviceImpl_CreateAdditionalSwapChain
,
4393 IWineD3DDeviceImpl_CreateVertexDeclaration
,
4394 IWineD3DDeviceImpl_CreateVertexShader
,
4395 IWineD3DDeviceImpl_CreatePixelShader
,
4397 /*** Odd functions **/
4398 IWineD3DDeviceImpl_EvictManagedResources
,
4399 IWineD3DDeviceImpl_GetAvailableTextureMem
,
4400 IWineD3DDeviceImpl_GetBackBuffer
,
4401 IWineD3DDeviceImpl_GetCreationParameters
,
4402 IWineD3DDeviceImpl_GetDeviceCaps
,
4403 IWineD3DDeviceImpl_GetDirect3D
,
4404 IWineD3DDeviceImpl_GetDisplayMode
,
4405 IWineD3DDeviceImpl_GetNumberOfSwapChains
,
4406 IWineD3DDeviceImpl_GetRasterStatus
,
4407 IWineD3DDeviceImpl_GetSwapChain
,
4408 IWineD3DDeviceImpl_Reset
,
4409 IWineD3DDeviceImpl_SetDialogBoxMode
,
4410 IWineD3DDeviceImpl_SetCursorProperties
,
4411 IWineD3DDeviceImpl_SetCursorPosition
,
4412 IWineD3DDeviceImpl_ShowCursor
,
4413 IWineD3DDeviceImpl_TestCooperativeLevel
,
4414 /*** Getters and setters **/
4415 IWineD3DDeviceImpl_SetClipPlane
,
4416 IWineD3DDeviceImpl_GetClipPlane
,
4417 IWineD3DDeviceImpl_SetClipStatus
,
4418 IWineD3DDeviceImpl_GetClipStatus
,
4419 IWineD3DDeviceImpl_SetCurrentTexturePalette
,
4420 IWineD3DDeviceImpl_GetCurrentTexturePalette
,
4421 IWineD3DDeviceImpl_SetDepthStencilSurface
,
4422 IWineD3DDeviceImpl_GetDepthStencilSurface
,
4423 IWineD3DDeviceImpl_SetFVF
,
4424 IWineD3DDeviceImpl_GetFVF
,
4425 IWineD3DDeviceImpl_SetGammaRamp
,
4426 IWineD3DDeviceImpl_GetGammaRamp
,
4427 IWineD3DDeviceImpl_SetIndices
,
4428 IWineD3DDeviceImpl_GetIndices
,
4429 IWineD3DDeviceImpl_SetLight
,
4430 IWineD3DDeviceImpl_GetLight
,
4431 IWineD3DDeviceImpl_SetLightEnable
,
4432 IWineD3DDeviceImpl_GetLightEnable
,
4433 IWineD3DDeviceImpl_SetMaterial
,
4434 IWineD3DDeviceImpl_GetMaterial
,
4435 IWineD3DDeviceImpl_SetNPatchMode
,
4436 IWineD3DDeviceImpl_GetNPatchMode
,
4437 IWineD3DDeviceImpl_SetPaletteEntries
,
4438 IWineD3DDeviceImpl_GetPaletteEntries
,
4439 IWineD3DDeviceImpl_SetPixelShader
,
4440 IWineD3DDeviceImpl_GetPixelShader
,
4441 IWineD3DDeviceImpl_SetPixelShaderConstantB
,
4442 IWineD3DDeviceImpl_GetPixelShaderConstantB
,
4443 IWineD3DDeviceImpl_SetPixelShaderConstantI
,
4444 IWineD3DDeviceImpl_GetPixelShaderConstantI
,
4445 IWineD3DDeviceImpl_SetPixelShaderConstantF
,
4446 IWineD3DDeviceImpl_GetPixelShaderConstantF
,
4447 IWineD3DDeviceImpl_SetRenderState
,
4448 IWineD3DDeviceImpl_GetRenderState
,
4449 IWineD3DDeviceImpl_SetRenderTarget
,
4450 IWineD3DDeviceImpl_GetRenderTarget
,
4451 IWineD3DDeviceImpl_SetSamplerState
,
4452 IWineD3DDeviceImpl_GetSamplerState
,
4453 IWineD3DDeviceImpl_SetScissorRect
,
4454 IWineD3DDeviceImpl_GetScissorRect
,
4455 IWineD3DDeviceImpl_SetSoftwareVertexProcessing
,
4456 IWineD3DDeviceImpl_GetSoftwareVertexProcessing
,
4457 IWineD3DDeviceImpl_SetStreamSource
,
4458 IWineD3DDeviceImpl_GetStreamSource
,
4459 IWineD3DDeviceImpl_SetStreamSourceFreq
,
4460 IWineD3DDeviceImpl_GetStreamSourceFreq
,
4461 IWineD3DDeviceImpl_SetTexture
,
4462 IWineD3DDeviceImpl_GetTexture
,
4463 IWineD3DDeviceImpl_SetTextureStageState
,
4464 IWineD3DDeviceImpl_GetTextureStageState
,
4465 IWineD3DDeviceImpl_SetTransform
,
4466 IWineD3DDeviceImpl_GetTransform
,
4467 IWineD3DDeviceImpl_SetVertexDeclaration
,
4468 IWineD3DDeviceImpl_GetVertexDeclaration
,
4469 IWineD3DDeviceImpl_SetVertexShader
,
4470 IWineD3DDeviceImpl_GetVertexShader
,
4471 IWineD3DDeviceImpl_SetVertexShaderConstantB
,
4472 IWineD3DDeviceImpl_GetVertexShaderConstantB
,
4473 IWineD3DDeviceImpl_SetVertexShaderConstantI
,
4474 IWineD3DDeviceImpl_GetVertexShaderConstantI
,
4475 IWineD3DDeviceImpl_SetVertexShaderConstantF
,
4476 IWineD3DDeviceImpl_GetVertexShaderConstantF
,
4477 IWineD3DDeviceImpl_SetViewport
,
4478 IWineD3DDeviceImpl_GetViewport
,
4479 IWineD3DDeviceImpl_MultiplyTransform
,
4480 IWineD3DDeviceImpl_ValidateDevice
,
4481 IWineD3DDeviceImpl_ProcessVertices
,
4482 /*** State block ***/
4483 IWineD3DDeviceImpl_BeginStateBlock
,
4484 IWineD3DDeviceImpl_EndStateBlock
,
4485 /*** Scene management ***/
4486 IWineD3DDeviceImpl_BeginScene
,
4487 IWineD3DDeviceImpl_EndScene
,
4488 IWineD3DDeviceImpl_Present
,
4489 IWineD3DDeviceImpl_Clear
,
4491 IWineD3DDeviceImpl_DrawPrimitive
,
4492 IWineD3DDeviceImpl_DrawIndexedPrimitive
,
4493 IWineD3DDeviceImpl_DrawPrimitiveUP
,
4494 IWineD3DDeviceImpl_DrawIndexedPrimitiveUP
,
4495 IWineD3DDeviceImpl_DrawRectPatch
,
4496 IWineD3DDeviceImpl_DrawTriPatch
,
4497 IWineD3DDeviceImpl_DeletePatch
,
4498 IWineD3DDeviceImpl_ColorFill
,
4499 IWineD3DDeviceImpl_UpdateTexture
,
4500 IWineD3DDeviceImpl_UpdateSurface
,
4501 IWineD3DDeviceImpl_StretchRect
,
4502 IWineD3DDeviceImpl_GetRenderTargetData
,
4503 IWineD3DDeviceImpl_GetFrontBufferData
,
4504 /*** Internal use IWineD3DDevice methods ***/
4505 IWineD3DDeviceImpl_SetupTextureStates