2 * state block implementation
4 * Copyright 2002 Raphael Junqueira
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "wined3d_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
26 #define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->wineD3DDevice)->wineD3D))->gl_info
28 HRESULT WINAPI
IWineD3DStateBlockImpl_GetParent(IWineD3DStateBlock
*iface
, IUnknown
**pParent
) {
29 IWineD3DStateBlockImpl
*This
= (IWineD3DStateBlockImpl
*)iface
;
30 IUnknown_AddRef(This
->parent
);
31 *pParent
= This
->parent
;
35 HRESULT WINAPI
IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStateBlock
* iface
) {
36 IWineD3DStateBlockImpl
*This
= (IWineD3DStateBlockImpl
*)iface
;
37 IWineD3DDeviceImpl
*ThisDevice
= (IWineD3DDeviceImpl
*)(This
->wineD3DDevice
);
48 /* Note this may have a large overhead but it should only be executed
49 once, in order to initialize the complete state of the device and
50 all opengl equivalents */
51 TRACE("-----------------------> Setting up device defaults...\n");
52 This
->blockType
= D3DSBT_ALL
;
54 /* FIXME: Set some of the defaults for lights, transforms etc */
55 memcpy(&This
->transforms
[D3DTS_PROJECTION
], &identity
, sizeof(identity
));
56 memcpy(&This
->transforms
[D3DTS_VIEW
], &identity
, sizeof(identity
));
57 for (i
= 0; i
< 256; ++i
) {
58 memcpy(&This
->transforms
[D3DTS_WORLDMATRIX(i
)], &identity
, sizeof(identity
));
62 if (ThisDevice
->presentParms
.EnableAutoDepthStencil
) {
63 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_ZENABLE
, D3DZB_TRUE
);
65 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_ZENABLE
, D3DZB_FALSE
);
67 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_FILLMODE
, D3DFILL_SOLID
);
68 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_SHADEMODE
, D3DSHADE_GOURAUD
);
70 lp
.lp
.wRepeatFactor
= 0; lp
.lp
.wLinePattern
= 0;
71 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_LINEPATTERN
, lp
.d
);
72 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_ZWRITEENABLE
, TRUE
);
73 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_ALPHATESTENABLE
, FALSE
);
74 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_LASTPIXEL
, TRUE
);
75 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_SRCBLEND
, D3DBLEND_ONE
);
76 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_DESTBLEND
, D3DBLEND_ZERO
);
77 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_CULLMODE
, D3DCULL_CCW
);
78 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_ZFUNC
, D3DCMP_LESSEQUAL
);
79 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_ALPHAFUNC
, D3DCMP_ALWAYS
);
80 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_ALPHAREF
, 0xff); /*??*/
81 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_DITHERENABLE
, FALSE
);
82 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_ALPHABLENDENABLE
, FALSE
);
83 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_FOGENABLE
, FALSE
);
84 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_SPECULARENABLE
, FALSE
);
85 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_ZVISIBLE
, 0);
86 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_FOGCOLOR
, 0);
87 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_FOGTABLEMODE
, D3DFOG_NONE
);
89 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_FOGSTART
, tmpfloat
.d
);
91 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_FOGEND
, tmpfloat
.d
);
93 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_FOGDENSITY
, tmpfloat
.d
);
94 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_EDGEANTIALIAS
, FALSE
);
95 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_ZBIAS
, 0);
96 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_RANGEFOGENABLE
, FALSE
);
97 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_STENCILENABLE
, FALSE
);
98 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_STENCILFAIL
, D3DSTENCILOP_KEEP
);
99 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_STENCILZFAIL
, D3DSTENCILOP_KEEP
);
100 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_STENCILPASS
, D3DSTENCILOP_KEEP
);
102 /* Setting stencil func also uses values for stencil ref/mask, so manually set defaults
103 * so only a single call performed (and ensure defaults initialized before making that call)
105 * IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_STENCILREF, 0);
106 * IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_STENCILMASK, 0xFFFFFFFF);
108 This
->renderState
[D3DRS_STENCILREF
] = 0;
109 This
->renderState
[D3DRS_STENCILMASK
] = 0xFFFFFFFF;
110 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_STENCILFUNC
, D3DCMP_ALWAYS
);
111 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_STENCILWRITEMASK
, 0xFFFFFFFF);
112 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_TEXTUREFACTOR
, 0xFFFFFFFF);
113 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_WRAP0
, 0);
114 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_WRAP1
, 0);
115 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_WRAP2
, 0);
116 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_WRAP3
, 0);
117 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_WRAP4
, 0);
118 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_WRAP5
, 0);
119 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_WRAP6
, 0);
120 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_WRAP7
, 0);
121 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_CLIPPING
, TRUE
);
122 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_LIGHTING
, TRUE
);
123 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_AMBIENT
, 0);
124 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_FOGVERTEXMODE
, D3DFOG_NONE
);
125 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_COLORVERTEX
, TRUE
);
126 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_LOCALVIEWER
, TRUE
);
127 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_NORMALIZENORMALS
, FALSE
);
128 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_DIFFUSEMATERIALSOURCE
, D3DMCS_COLOR1
);
129 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_SPECULARMATERIALSOURCE
, D3DMCS_COLOR2
);
130 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_AMBIENTMATERIALSOURCE
, D3DMCS_COLOR2
);
131 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_EMISSIVEMATERIALSOURCE
, D3DMCS_MATERIAL
);
132 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_VERTEXBLEND
, D3DVBF_DISABLE
);
133 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_CLIPPLANEENABLE
, 0);
134 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_SOFTWAREVERTEXPROCESSING
, FALSE
);
136 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_POINTSIZE
, tmpfloat
.d
);
138 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_POINTSIZE_MIN
, tmpfloat
.d
);
139 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_POINTSPRITEENABLE
, FALSE
);
140 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_POINTSCALEENABLE
, FALSE
);
141 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_POINTSCALE_A
, TRUE
);
142 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_POINTSCALE_B
, TRUE
);
143 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_POINTSCALE_C
, TRUE
);
144 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_MULTISAMPLEANTIALIAS
, TRUE
);
145 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_MULTISAMPLEMASK
, 0xFFFFFFFF);
146 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_PATCHEDGESTYLE
, D3DPATCHEDGE_DISCRETE
);
148 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_PATCHSEGMENTS
, tmpfloat
.d
);
149 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_DEBUGMONITORTOKEN
, D3DDMT_DISABLE
);
151 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_POINTSIZE_MAX
, tmpfloat
.d
);
152 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_INDEXEDVERTEXBLENDENABLE
, FALSE
);
153 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_COLORWRITEENABLE
, 0x0000000F);
155 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_TWEENFACTOR
, tmpfloat
.d
);
156 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_BLENDOP
, D3DBLENDOP_ADD
);
157 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_POSITIONORDER
, D3DORDER_CUBIC
);
158 IWineD3DDevice_SetRenderState(This
->wineD3DDevice
, D3DRS_NORMALORDER
, D3DORDER_LINEAR
);
160 /** clipping status */
161 This
->clip_status
.ClipUnion
= 0;
162 This
->clip_status
.ClipIntersection
= 0xFFFFFFFF;
164 /* Texture Stage States - Put directly into state block, we will call function below */
165 for (i
= 0; i
< GL_LIMITS(textures
); i
++) {
166 TRACE("Setting up default texture states for texture Stage %d\n", i
);
167 memcpy(&This
->transforms
[D3DTS_TEXTURE0
+ i
], &identity
, sizeof(identity
));
168 This
->textureState
[i
][D3DTSS_COLOROP
] = (i
==0)? D3DTOP_MODULATE
: D3DTOP_DISABLE
;
169 This
->textureState
[i
][D3DTSS_COLORARG1
] = D3DTA_TEXTURE
;
170 This
->textureState
[i
][D3DTSS_COLORARG2
] = D3DTA_CURRENT
;
171 This
->textureState
[i
][D3DTSS_ALPHAOP
] = (i
==0)? D3DTOP_SELECTARG1
: D3DTOP_DISABLE
;
172 This
->textureState
[i
][D3DTSS_ALPHAARG1
] = D3DTA_TEXTURE
;
173 This
->textureState
[i
][D3DTSS_ALPHAARG2
] = D3DTA_CURRENT
;
174 This
->textureState
[i
][D3DTSS_BUMPENVMAT00
] = (DWORD
) 0.0;
175 This
->textureState
[i
][D3DTSS_BUMPENVMAT01
] = (DWORD
) 0.0;
176 This
->textureState
[i
][D3DTSS_BUMPENVMAT10
] = (DWORD
) 0.0;
177 This
->textureState
[i
][D3DTSS_BUMPENVMAT11
] = (DWORD
) 0.0;
178 This
->textureState
[i
][D3DTSS_TEXCOORDINDEX
] = i
;
179 This
->textureState
[i
][D3DTSS_ADDRESSU
] = D3DTADDRESS_WRAP
;
180 This
->textureState
[i
][D3DTSS_ADDRESSV
] = D3DTADDRESS_WRAP
;
181 This
->textureState
[i
][D3DTSS_BORDERCOLOR
] = 0x00;
182 This
->textureState
[i
][D3DTSS_MAGFILTER
] = D3DTEXF_POINT
;
183 This
->textureState
[i
][D3DTSS_MINFILTER
] = D3DTEXF_POINT
;
184 This
->textureState
[i
][D3DTSS_MIPFILTER
] = D3DTEXF_NONE
;
185 This
->textureState
[i
][D3DTSS_MIPMAPLODBIAS
] = 0;
186 This
->textureState
[i
][D3DTSS_MAXMIPLEVEL
] = 0;
187 This
->textureState
[i
][D3DTSS_MAXANISOTROPY
] = 1;
188 This
->textureState
[i
][D3DTSS_BUMPENVLSCALE
] = (DWORD
) 0.0;
189 This
->textureState
[i
][D3DTSS_BUMPENVLOFFSET
] = (DWORD
) 0.0;
190 This
->textureState
[i
][D3DTSS_TEXTURETRANSFORMFLAGS
] = D3DTTFF_DISABLE
;
191 This
->textureState
[i
][D3DTSS_ADDRESSW
] = D3DTADDRESS_WRAP
;
192 This
->textureState
[i
][D3DTSS_COLORARG0
] = D3DTA_CURRENT
;
193 This
->textureState
[i
][D3DTSS_ALPHAARG0
] = D3DTA_CURRENT
;
194 This
->textureState
[i
][D3DTSS_RESULTARG
] = D3DTA_CURRENT
;
197 /* Under DirectX you can have texture stage operations even if no texture is
198 bound, whereas opengl will only do texture operations when a valid texture is
199 bound. We emulate this by creating dummy textures and binding them to each
200 texture stage, but disable all stages by default. Hence if a stage is enabled
201 then the default texture will kick in until replaced by a SetTexture call */
205 for (i
= 0; i
< GL_LIMITS(textures
); i
++) {
208 /* Note this avoids calling settexture, so pretend it has been called */
209 This
->set
.textures
[i
] = TRUE
;
210 This
->changed
.textures
[i
] = TRUE
;
211 This
->textures
[i
] = NULL
;
213 /* Make appropriate texture active */
214 if (GL_SUPPORT(ARB_MULTITEXTURE
)) {
217 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
220 /* Generate an opengl texture name */
221 glGenTextures(1, &ThisDevice
->dummyTextureName
[i
]);
222 checkGLcall("glGenTextures");
223 TRACE("Dummy Texture %d given name %d\n", i
, ThisDevice
->dummyTextureName
[i
]);
225 /* Generate a dummy 1d texture */
226 This
->textureDimensions
[i
] = GL_TEXTURE_1D
;
227 glBindTexture(GL_TEXTURE_1D
, ThisDevice
->dummyTextureName
[i
]);
228 checkGLcall("glBindTexture");
230 glTexImage1D(GL_TEXTURE_1D
, 0, GL_LUMINANCE
, 1, 0, GL_LUMINANCE
, GL_UNSIGNED_BYTE
, &white
);
231 checkGLcall("glTexImage1D");
233 /* Reapply all the texture state information to this texture */
234 IWineD3DDevice_SetupTextureStates(This
->wineD3DDevice
, i
, REAPPLY_ALL
);
239 #if 0 /* TODO: Palette support */
240 /* defaulting palettes */
241 for (i
= 0; i
< MAX_PALETTES
; ++i
) {
243 for (j
= 0; j
< 256; ++j
) {
244 This
->palettes
[i
][j
].peRed
= 0xFF;
245 This
->palettes
[i
][j
].peGreen
= 0xFF;
246 This
->palettes
[i
][j
].peBlue
= 0xFF;
247 This
->palettes
[i
][j
].peFlags
= 0xFF;
250 This
->currentPalette
= 0;
251 #endif /* TODO: Palette support */
253 TRACE("-----------------------> Device defaults now set up...\n");
257 /**********************************************************
258 * IUnknown parts follows
259 **********************************************************/
260 HRESULT WINAPI
IWineD3DStateBlockImpl_QueryInterface(IWineD3DStateBlock
*iface
,REFIID riid
,LPVOID
*ppobj
)
262 return E_NOINTERFACE
;
265 ULONG WINAPI
IWineD3DStateBlockImpl_AddRef(IWineD3DStateBlock
*iface
) {
266 IWineD3DStateBlockImpl
*This
= (IWineD3DStateBlockImpl
*)iface
;
267 TRACE("(%p) : AddRef increasing from %ld\n", This
, This
->ref
);
268 return InterlockedIncrement(&This
->ref
);
271 ULONG WINAPI
IWineD3DStateBlockImpl_Release(IWineD3DStateBlock
*iface
) {
272 IWineD3DStateBlockImpl
*This
= (IWineD3DStateBlockImpl
*)iface
;
274 TRACE("(%p) : Releasing from %ld\n", This
, This
->ref
);
275 ref
= InterlockedDecrement(&This
->ref
);
277 IWineD3DDevice_Release(This
->wineD3DDevice
);
278 HeapFree(GetProcessHeap(), 0, This
);
283 /**********************************************************
284 * IWineD3DStateBlock VTbl follows
285 **********************************************************/
287 IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl
=
289 IWineD3DStateBlockImpl_QueryInterface
,
290 IWineD3DStateBlockImpl_AddRef
,
291 IWineD3DStateBlockImpl_Release
,
292 IWineD3DStateBlockImpl_GetParent
,
293 IWineD3DStateBlockImpl_InitStartupStateBlock