1 /* Direct3D Common functions
2 * Copyright (c) 1998 Lionel ULMER
4 * This file contains all MESA common code
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define NONAMELESSUNION
24 #define NONAMELESSSTRUCT
29 #include "wine/debug.h"
31 #include "mesa_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
35 GLenum
convert_D3D_compare_to_GL(D3DCMPFUNC dwRenderState
)
37 switch (dwRenderState
) {
38 case D3DCMP_NEVER
: return GL_NEVER
;
39 case D3DCMP_LESS
: return GL_LESS
;
40 case D3DCMP_EQUAL
: return GL_EQUAL
;
41 case D3DCMP_LESSEQUAL
: return GL_LEQUAL
;
42 case D3DCMP_GREATER
: return GL_GREATER
;
43 case D3DCMP_NOTEQUAL
: return GL_NOTEQUAL
;
44 case D3DCMP_GREATEREQUAL
: return GL_GEQUAL
;
45 case D3DCMP_ALWAYS
: return GL_ALWAYS
;
46 default: ERR("Unexpected compare type %d !\n", dwRenderState
);
51 GLenum
convert_D3D_stencilop_to_GL(D3DSTENCILOP dwRenderState
)
53 switch (dwRenderState
) {
54 case D3DSTENCILOP_KEEP
: return GL_KEEP
;
55 case D3DSTENCILOP_ZERO
: return GL_ZERO
;
56 case D3DSTENCILOP_REPLACE
: return GL_REPLACE
;
57 case D3DSTENCILOP_INCRSAT
: return GL_INCR
;
58 case D3DSTENCILOP_DECRSAT
: return GL_DECR
;
59 case D3DSTENCILOP_INVERT
: return GL_INVERT
;
60 case D3DSTENCILOP_INCR
: WARN("D3DSTENCILOP_INCR not properly handled !\n"); return GL_INCR
;
61 case D3DSTENCILOP_DECR
: WARN("D3DSTENCILOP_DECR not properly handled !\n"); return GL_DECR
;
62 default: ERR("Unexpected compare type %d !\n", dwRenderState
);
67 GLenum
convert_D3D_blendop_to_GL(D3DBLEND dwRenderState
)
69 switch ((D3DBLEND
) dwRenderState
) {
70 case D3DBLEND_ZERO
: return GL_ZERO
;
71 case D3DBLEND_ONE
: return GL_ONE
;
72 case D3DBLEND_SRCALPHA
: return GL_SRC_ALPHA
;
73 case D3DBLEND_INVSRCALPHA
: return GL_ONE_MINUS_SRC_ALPHA
;
74 case D3DBLEND_DESTALPHA
: return GL_DST_ALPHA
;
75 case D3DBLEND_INVDESTALPHA
: return GL_ONE_MINUS_DST_ALPHA
;
76 case D3DBLEND_DESTCOLOR
: return GL_DST_COLOR
;
77 case D3DBLEND_INVDESTCOLOR
: return GL_ONE_MINUS_DST_COLOR
;
78 case D3DBLEND_SRCALPHASAT
: return GL_SRC_ALPHA_SATURATE
;
79 case D3DBLEND_SRCCOLOR
: return GL_SRC_COLOR
;
80 case D3DBLEND_INVSRCCOLOR
: return GL_ONE_MINUS_SRC_COLOR
;
81 default: ERR("Unhandled blend mode %d !\n", dwRenderState
); return GL_ZERO
;
85 void set_render_state(IDirect3DDeviceImpl
* This
,
86 D3DRENDERSTATETYPE dwRenderStateType
, STATEBLOCK
*lpStateBlock
)
88 DWORD dwRenderState
= lpStateBlock
->render_state
[dwRenderStateType
- 1];
89 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
91 TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType
), dwRenderState
);
93 /* First, all the stipple patterns */
94 if ((dwRenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
) &&
95 (dwRenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)) {
96 ERR("Unhandled dwRenderStateType stipple %d!\n",dwRenderStateType
);
100 /* All others state variables */
101 switch (dwRenderStateType
) {
102 case D3DRENDERSTATE_TEXTUREHANDLE
: { /* 1 */
103 IDirectDrawSurfaceImpl
*tex
= (IDirectDrawSurfaceImpl
*) dwRenderState
;
105 IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This
, IDirect3DDevice7
),
107 ICOM_INTERFACE(tex
, IDirectDrawSurface7
));
110 case D3DRENDERSTATE_ANTIALIAS
: /* 2 */
112 ERR("D3DRENDERSTATE_ANTIALIAS not supported yet !\n");
115 case D3DRENDERSTATE_TEXTUREADDRESSU
: /* 44 */
116 case D3DRENDERSTATE_TEXTUREADDRESSV
: /* 45 */
117 case D3DRENDERSTATE_TEXTUREADDRESS
: { /* 3 */
118 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType
;
120 if (dwRenderStateType
== D3DRENDERSTATE_TEXTUREADDRESS
) d3dTexStageStateType
= D3DTSS_ADDRESS
;
121 else if (dwRenderStateType
== D3DRENDERSTATE_TEXTUREADDRESSU
) d3dTexStageStateType
= D3DTSS_ADDRESSU
;
122 else d3dTexStageStateType
= D3DTSS_ADDRESSV
;
124 IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This
, IDirect3DDevice7
),
125 0, d3dTexStageStateType
,
129 case D3DRENDERSTATE_TEXTUREPERSPECTIVE
: /* 4 */
131 glHint(GL_PERSPECTIVE_CORRECTION_HINT
, GL_NICEST
);
133 glHint(GL_PERSPECTIVE_CORRECTION_HINT
, GL_FASTEST
);
136 case D3DRENDERSTATE_WRAPU
: /* 5 */
137 case D3DRENDERSTATE_WRAPV
: /* 6 */
138 case D3DRENDERSTATE_WRAP0
: /* 128 */
139 case D3DRENDERSTATE_WRAP1
: /* 129 */
140 case D3DRENDERSTATE_WRAP2
: /* 130 */
141 case D3DRENDERSTATE_WRAP3
: /* 131 */
142 case D3DRENDERSTATE_WRAP4
: /* 132 */
143 case D3DRENDERSTATE_WRAP5
: /* 133 */
144 case D3DRENDERSTATE_WRAP6
: /* 134 */
145 case D3DRENDERSTATE_WRAP7
: /* 135 */
147 ERR("Texture WRAP modes unsupported by OpenGL.. Expect graphical glitches !\n");
150 case D3DRENDERSTATE_ZENABLE
: /* 7 */
151 /* To investigate : in OpenGL, if we disable the depth test, the Z buffer will NOT be
152 updated either.. No idea about what happens in D3D.
154 Maybe replacing the Z function by ALWAYS would be a better idea. */
155 if (dwRenderState
== D3DZB_TRUE
) {
156 if (glThis
->depth_test
== FALSE
) {
157 glEnable(GL_DEPTH_TEST
);
158 glThis
->depth_test
= TRUE
;
160 } else if (dwRenderState
== D3DZB_FALSE
) {
161 if (glThis
->depth_test
== TRUE
) {
162 glDisable(GL_DEPTH_TEST
);
163 glThis
->depth_test
= FALSE
;
166 if (glThis
->depth_test
== FALSE
) {
167 glEnable(GL_DEPTH_TEST
);
168 glThis
->depth_test
= TRUE
;
170 WARN(" w-buffering not supported.\n");
174 case D3DRENDERSTATE_FILLMODE
: /* 8 */
175 switch ((D3DFILLMODE
) dwRenderState
) {
177 glPolygonMode(GL_FRONT_AND_BACK
,GL_POINT
);
179 case D3DFILL_WIREFRAME
:
180 glPolygonMode(GL_FRONT_AND_BACK
,GL_LINE
);
183 glPolygonMode(GL_FRONT_AND_BACK
,GL_FILL
);
186 ERR("Unhandled fill mode %ld !\n",dwRenderState
);
190 case D3DRENDERSTATE_SHADEMODE
: /* 9 */
191 switch ((D3DSHADEMODE
) dwRenderState
) {
193 glShadeModel(GL_FLAT
);
195 case D3DSHADE_GOURAUD
:
196 glShadeModel(GL_SMOOTH
);
199 ERR("Unhandled shade mode %ld !\n",dwRenderState
);
203 case D3DRENDERSTATE_ZWRITEENABLE
: /* 14 */
204 if ((dwRenderState
!= FALSE
) && (glThis
->depth_mask
== FALSE
))
205 glDepthMask(GL_TRUE
);
206 else if ((dwRenderState
== FALSE
) && (glThis
->depth_mask
!= FALSE
))
207 glDepthMask(GL_FALSE
);
208 glThis
->depth_mask
= dwRenderState
;
211 case D3DRENDERSTATE_ALPHATESTENABLE
: /* 15 */
212 if ((dwRenderState
!= 0) && (glThis
->alpha_test
== FALSE
))
213 glEnable(GL_ALPHA_TEST
);
214 else if ((dwRenderState
== 0) && (glThis
->alpha_test
!= FALSE
))
215 glDisable(GL_ALPHA_TEST
);
216 glThis
->alpha_test
= dwRenderState
;
219 case D3DRENDERSTATE_TEXTUREMAG
: { /* 17 */
220 DWORD tex_mag
= 0xFFFFFFFF;
222 switch ((D3DTEXTUREFILTER
) dwRenderState
) {
223 case D3DFILTER_NEAREST
:
224 tex_mag
= D3DTFG_POINT
;
226 case D3DFILTER_LINEAR
:
227 tex_mag
= D3DTFG_LINEAR
;
230 ERR("Unhandled texture mag %ld !\n",dwRenderState
);
233 if (tex_mag
!= 0xFFFFFFFF) {
234 IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This
, IDirect3DDevice7
), 0, D3DTSS_MAGFILTER
, tex_mag
);
238 case D3DRENDERSTATE_TEXTUREMIN
: { /* 18 */
239 DWORD tex_min
= 0xFFFFFFFF;
241 switch ((D3DTEXTUREFILTER
) dwRenderState
) {
242 case D3DFILTER_NEAREST
:
243 tex_min
= D3DTFN_POINT
;
245 case D3DFILTER_LINEAR
:
246 tex_min
= D3DTFN_LINEAR
;
249 ERR("Unhandled texture min %ld !\n",dwRenderState
);
252 if (tex_min
!= 0xFFFFFFFF) {
253 IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This
, IDirect3DDevice7
), 0, D3DTSS_MINFILTER
, tex_min
);
257 case D3DRENDERSTATE_SRCBLEND
: /* 19 */
258 case D3DRENDERSTATE_DESTBLEND
: /* 20 */
259 glBlendFunc(convert_D3D_blendop_to_GL(lpStateBlock
->render_state
[D3DRENDERSTATE_SRCBLEND
- 1]),
260 convert_D3D_blendop_to_GL(lpStateBlock
->render_state
[D3DRENDERSTATE_DESTBLEND
- 1]));
263 case D3DRENDERSTATE_TEXTUREMAPBLEND
: { /* 21 */
264 IDirect3DDevice7
*d3ddev
= ICOM_INTERFACE(This
, IDirect3DDevice7
);
266 switch ((D3DTEXTUREBLEND
) dwRenderState
) {
267 case D3DTBLEND_DECAL
:
268 if (glThis
->current_tex_env
!= GL_REPLACE
) {
269 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
270 glThis
->current_tex_env
= GL_REPLACE
;
273 case D3DTBLEND_DECALALPHA
:
274 if (glThis
->current_tex_env
!= GL_REPLACE
) {
275 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_DECAL
);
276 glThis
->current_tex_env
= GL_DECAL
;
279 case D3DTBLEND_MODULATE
:
280 if (glThis
->current_tex_env
!= GL_MODULATE
) {
281 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
282 glThis
->current_tex_env
= GL_MODULATE
;
285 case D3DTBLEND_MODULATEALPHA
:
286 IDirect3DDevice7_SetTextureStageState(d3ddev
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
287 IDirect3DDevice7_SetTextureStageState(d3ddev
, 0, D3DTSS_ALPHAARG1
, D3DTA_TEXTURE
);
288 IDirect3DDevice7_SetTextureStageState(d3ddev
, 0, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
289 IDirect3DDevice7_SetTextureStageState(d3ddev
, 0, D3DTSS_ALPHAARG2
, D3DTA_CURRENT
);
290 IDirect3DDevice7_SetTextureStageState(d3ddev
, 0, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
291 IDirect3DDevice7_SetTextureStageState(d3ddev
, 0, D3DTSS_ALPHAOP
, D3DTOP_MODULATE
);
294 ERR("Unhandled texture environment %ld !\n",dwRenderState
);
298 case D3DRENDERSTATE_CULLMODE
: /* 22 */
299 switch ((D3DCULL
) dwRenderState
) {
301 if (glThis
->cull_face
!= 0) {
302 glDisable(GL_CULL_FACE
);
303 glThis
->cull_face
= 0;
307 if (glThis
->cull_face
== 0) {
308 glEnable(GL_CULL_FACE
);
309 glThis
->cull_face
= 1;
315 if (glThis
->cull_face
== 0) {
316 glEnable(GL_CULL_FACE
);
317 glThis
->cull_face
= 1;
323 ERR("Unhandled cull mode %ld !\n",dwRenderState
);
327 case D3DRENDERSTATE_ZFUNC
: /* 23 */
328 glDepthFunc(convert_D3D_compare_to_GL(dwRenderState
));
331 case D3DRENDERSTATE_ALPHAREF
: /* 24 */
332 case D3DRENDERSTATE_ALPHAFUNC
: /* 25 */
333 glAlphaFunc(convert_D3D_compare_to_GL(lpStateBlock
->render_state
[D3DRENDERSTATE_ALPHAFUNC
- 1]),
334 (lpStateBlock
->render_state
[D3DRENDERSTATE_ALPHAREF
- 1] & 0x000000FF) / 255.0);
337 case D3DRENDERSTATE_DITHERENABLE
: /* 26 */
341 glDisable(GL_DITHER
);
344 case D3DRENDERSTATE_ALPHABLENDENABLE
: /* 27 */
345 if ((dwRenderState
!= 0) && (glThis
->blending
== 0)) {
347 } else if ((dwRenderState
== 0) && (glThis
->blending
!= 0)) {
350 glThis
->blending
= dwRenderState
;
353 case D3DRENDERSTATE_FOGENABLE
: /* 28 */
354 /* Nothing to do here. Only the storage matters :-) */
357 case D3DRENDERSTATE_SPECULARENABLE
: /* 29 */
359 ERR(" Specular Lighting not supported yet.\n");
362 case D3DRENDERSTATE_SUBPIXEL
: /* 31 */
363 case D3DRENDERSTATE_SUBPIXELX
: /* 32 */
364 /* We do not support this anyway, so why protest :-) */
367 case D3DRENDERSTATE_STIPPLEDALPHA
: /* 33 */
369 ERR(" Stippled Alpha not supported yet.\n");
372 case D3DRENDERSTATE_FOGCOLOR
: { /* 34 */
374 color
[0] = ((dwRenderState
>> 16) & 0xFF)/255.0f
;
375 color
[1] = ((dwRenderState
>> 8) & 0xFF)/255.0f
;
376 color
[2] = ((dwRenderState
>> 0) & 0xFF)/255.0f
;
377 color
[3] = ((dwRenderState
>> 24) & 0xFF)/255.0f
;
378 glFogfv(GL_FOG_COLOR
,color
);
379 /* Note: glFogiv does not seem to work */
382 case D3DRENDERSTATE_FOGTABLEMODE
: /* 35 */
383 case D3DRENDERSTATE_FOGVERTEXMODE
: /* 140 */
384 case D3DRENDERSTATE_FOGSTART
: /* 36 */
385 case D3DRENDERSTATE_FOGEND
: /* 37 */
386 /* Nothing to do here. Only the storage matters :-) */
389 case D3DRENDERSTATE_FOGDENSITY
: /* 38 */
390 glFogi(GL_FOG_DENSITY
,*(float*)&dwRenderState
);
393 case D3DRENDERSTATE_COLORKEYENABLE
: /* 41 */
394 /* This needs to be fixed. */
395 if ((dwRenderState
!= 0) && (glThis
->blending
== 0)) {
397 } else if ((dwRenderState
== 0) && (glThis
->blending
!= 0)) {
400 glThis
->blending
= dwRenderState
;
403 case D3DRENDERSTATE_MIPMAPLODBIAS
: /* 46 */
404 IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This
, IDirect3DDevice7
),
405 0, D3DTSS_MIPMAPLODBIAS
,
409 case D3DRENDERSTATE_ZBIAS
: /* 47 */
410 /* This is a tad bit hacky.. But well, no idea how to do it better in OpenGL :-/ */
411 if (dwRenderState
== 0) {
412 glDisable(GL_POLYGON_OFFSET_FILL
);
413 glDisable(GL_POLYGON_OFFSET_LINE
);
414 glDisable(GL_POLYGON_OFFSET_POINT
);
416 glEnable(GL_POLYGON_OFFSET_FILL
);
417 glEnable(GL_POLYGON_OFFSET_LINE
);
418 glEnable(GL_POLYGON_OFFSET_POINT
);
419 glPolygonOffset(1.0, dwRenderState
* 1.0);
423 case D3DRENDERSTATE_FLUSHBATCH
: /* 50 */
426 case D3DRENDERSTATE_STENCILENABLE
: /* 52 */
427 if ((dwRenderState
!= 0) && (glThis
->stencil_test
== 0))
428 glEnable(GL_STENCIL_TEST
);
429 else if ((dwRenderState
== 0) && (glThis
->stencil_test
!= 0))
430 glDisable(GL_STENCIL_TEST
);
431 glThis
->stencil_test
= dwRenderState
;
434 case D3DRENDERSTATE_STENCILFAIL
: /* 53 */
435 case D3DRENDERSTATE_STENCILZFAIL
: /* 54 */
436 case D3DRENDERSTATE_STENCILPASS
: /* 55 */
437 glStencilOp(convert_D3D_stencilop_to_GL(lpStateBlock
->render_state
[D3DRENDERSTATE_STENCILFAIL
- 1]),
438 convert_D3D_stencilop_to_GL(lpStateBlock
->render_state
[D3DRENDERSTATE_STENCILZFAIL
- 1]),
439 convert_D3D_stencilop_to_GL(lpStateBlock
->render_state
[D3DRENDERSTATE_STENCILPASS
- 1]));
442 case D3DRENDERSTATE_STENCILFUNC
: /* 56 */
443 case D3DRENDERSTATE_STENCILREF
: /* 57 */
444 case D3DRENDERSTATE_STENCILMASK
: /* 58 */
445 glStencilFunc(convert_D3D_compare_to_GL(lpStateBlock
->render_state
[D3DRENDERSTATE_STENCILFUNC
- 1]),
446 lpStateBlock
->render_state
[D3DRENDERSTATE_STENCILREF
- 1],
447 lpStateBlock
->render_state
[D3DRENDERSTATE_STENCILMASK
- 1]);
450 case D3DRENDERSTATE_STENCILWRITEMASK
: /* 59 */
451 glStencilMask(dwRenderState
);
454 case D3DRENDERSTATE_TEXTUREFACTOR
: /* 60 */
455 /* Only the storage matters... */
458 case D3DRENDERSTATE_CLIPPING
: /* 136 */
459 case D3DRENDERSTATE_CLIPPLANEENABLE
: { /* 152 */
463 if (dwRenderStateType
== D3DRENDERSTATE_CLIPPING
) {
464 mask
= ((dwRenderState
) ?
465 (This
->state_block
.render_state
[D3DRENDERSTATE_CLIPPLANEENABLE
- 1]) : (0x00000000));
467 mask
= dwRenderState
;
469 for (i
= 0, runner
= 0x00000001; i
< This
->max_clipping_planes
; i
++, runner
= (runner
<< 1)) {
472 glGetIntegerv(GL_CLIP_PLANE0
+ i
, &enabled
);
473 if (enabled
== GL_FALSE
) {
474 glEnable(GL_CLIP_PLANE0
+ i
);
475 /* Need to force a transform change so that this clipping plane parameters are sent
478 glThis
->transform_state
= GL_TRANSFORM_NONE
;
481 glDisable(GL_CLIP_PLANE0
+ i
);
487 case D3DRENDERSTATE_LIGHTING
: /* 137 */
488 /* Nothing to do, only storage matters... */
491 case D3DRENDERSTATE_AMBIENT
: { /* 139 */
494 light
[0] = ((dwRenderState
>> 16) & 0xFF) / 255.0;
495 light
[1] = ((dwRenderState
>> 8) & 0xFF) / 255.0;
496 light
[2] = ((dwRenderState
>> 0) & 0xFF) / 255.0;
497 light
[3] = ((dwRenderState
>> 24) & 0xFF) / 255.0;
498 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, (float *) light
);
501 case D3DRENDERSTATE_COLORVERTEX
: /* 141 */
502 /* Nothing to do here.. Only storage matters */
505 case D3DRENDERSTATE_LOCALVIEWER
: /* 142 */
507 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER
, GL_TRUE
);
509 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER
, GL_FALSE
);
512 case D3DRENDERSTATE_NORMALIZENORMALS
: /* 143 */
514 glEnable(GL_NORMALIZE
);
515 glEnable(GL_RESCALE_NORMAL
);
517 glDisable(GL_NORMALIZE
);
518 glDisable(GL_RESCALE_NORMAL
);
522 case D3DRENDERSTATE_DIFFUSEMATERIALSOURCE
: /* 145 */
523 case D3DRENDERSTATE_SPECULARMATERIALSOURCE
: /* 146 */
524 case D3DRENDERSTATE_AMBIENTMATERIALSOURCE
: /* 147 */
525 case D3DRENDERSTATE_EMISSIVEMATERIALSOURCE
: /* 148 */
526 /* Nothing to do here. Only the storage matters :-) */
530 ERR("Unhandled dwRenderStateType %s (%08x) value : %08lx !\n",
531 _get_renderstate(dwRenderStateType
), dwRenderStateType
, dwRenderState
);
537 void store_render_state(IDirect3DDeviceImpl
*This
,
538 D3DRENDERSTATETYPE dwRenderStateType
, DWORD dwRenderState
, STATEBLOCK
*lpStateBlock
)
540 TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType
), dwRenderState
);
542 /* Some special cases first.. */
543 if (dwRenderStateType
== D3DRENDERSTATE_SRCBLEND
) {
544 if (dwRenderState
== D3DBLEND_BOTHSRCALPHA
) {
545 lpStateBlock
->render_state
[D3DRENDERSTATE_SRCBLEND
- 1] = D3DBLEND_SRCALPHA
;
546 lpStateBlock
->render_state
[D3DRENDERSTATE_DESTBLEND
- 1] = D3DBLEND_SRCALPHA
;
548 } else if (dwRenderState
== D3DBLEND_BOTHINVSRCALPHA
) {
549 lpStateBlock
->render_state
[D3DRENDERSTATE_SRCBLEND
- 1] = D3DBLEND_INVSRCALPHA
;
550 lpStateBlock
->render_state
[D3DRENDERSTATE_DESTBLEND
- 1] = D3DBLEND_INVSRCALPHA
;
553 } else if (dwRenderStateType
== D3DRENDERSTATE_TEXTUREADDRESS
) {
554 lpStateBlock
->render_state
[D3DRENDERSTATE_TEXTUREADDRESSU
- 1] = dwRenderState
;
555 lpStateBlock
->render_state
[D3DRENDERSTATE_TEXTUREADDRESSV
- 1] = dwRenderState
;
556 } else if (dwRenderStateType
== D3DRENDERSTATE_WRAPU
) {
558 lpStateBlock
->render_state
[D3DRENDERSTATE_WRAP0
] |= D3DWRAP_U
;
560 lpStateBlock
->render_state
[D3DRENDERSTATE_WRAP0
] &= ~D3DWRAP_U
;
561 } else if (dwRenderStateType
== D3DRENDERSTATE_WRAPV
) {
563 lpStateBlock
->render_state
[D3DRENDERSTATE_WRAP0
] |= D3DWRAP_V
;
565 lpStateBlock
->render_state
[D3DRENDERSTATE_WRAP0
] &= ~D3DWRAP_V
;
569 lpStateBlock
->render_state
[dwRenderStateType
- 1] = dwRenderState
;
572 void get_render_state(IDirect3DDeviceImpl
*This
,
573 D3DRENDERSTATETYPE dwRenderStateType
, LPDWORD lpdwRenderState
, STATEBLOCK
*lpStateBlock
)
575 *lpdwRenderState
= lpStateBlock
->render_state
[dwRenderStateType
- 1];
577 TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType
), *lpdwRenderState
);
580 void apply_render_state(IDirect3DDeviceImpl
*This
, STATEBLOCK
*lpStateBlock
)
583 TRACE("(%p,%p)\n", This
, lpStateBlock
);
584 for(i
= 0; i
< HIGHEST_RENDER_STATE
; i
++)
585 if (lpStateBlock
->set_flags
.render_state
[i
])
586 set_render_state(This
, i
+ 1, lpStateBlock
);
590 /* Texture management code.
592 - upload_surface_to_tex_memory_init initialize the code and computes the GL formats
593 according to the surface description.
595 - upload_surface_to_tex_memory does the real upload. If one buffer is split over
596 multiple textures, this can be called multiple times after the '_init' call. 'rect'
597 can be NULL if the whole buffer needs to be upload.
599 - upload_surface_to_tex_memory_release does the clean-up.
601 These functions are called in the following cases :
602 - texture management (ie to upload a D3D texture to GL when it changes).
603 - flush of the 'in-memory' frame buffer to the GL frame buffer using the texture
605 - use of the texture engine to simulate Blits to the 3D Device.
613 CONVERT_CK_4444_ARGB
,
618 CONVERT_CK_8888_ARGB
,
622 /* Note : we suppose that all the code calling this is protected by the GL lock... Otherwise bad things
624 static GLenum current_format
;
625 static GLenum current_pixel_format
;
626 static CONVERT_TYPES convert_type
;
627 static IDirectDrawSurfaceImpl
*current_surface
;
628 static GLuint current_level
;
629 static DWORD current_tex_width
;
630 static DWORD current_tex_height
;
631 static GLuint current_alignement_constraints
;
632 static int current_storage_width
;
634 HRESULT
upload_surface_to_tex_memory_init(IDirectDrawSurfaceImpl
*surf_ptr
, GLuint level
, GLenum
*current_internal_format
,
635 BOOLEAN need_to_alloc
, BOOLEAN need_alpha_ck
, DWORD tex_width
, DWORD tex_height
)
637 const DDPIXELFORMAT
* const src_pf
= &(surf_ptr
->surface_desc
.u4
.ddpfPixelFormat
);
639 BOOL colorkey_active
= need_alpha_ck
&& (surf_ptr
->surface_desc
.dwFlags
& DDSD_CKSRCBLT
);
640 GLenum internal_format
= GL_LUMINANCE
; /* A bogus value to be sure to have a nice Mesa warning :-) */
641 BYTE bpp
= GET_BPP(surf_ptr
->surface_desc
);
642 BOOL sub_texture
= TRUE
;
644 current_surface
= surf_ptr
;
645 current_level
= level
;
647 /* First, do some sanity checks ... */
648 if ((surf_ptr
->surface_desc
.u1
.lPitch
% bpp
) != 0) {
649 FIXME("Warning : pitch is not a multiple of BPP - not supported yet !\n");
651 /* In that case, no need to have any alignement constraints... */
652 if (current_alignement_constraints
!= 1) {
653 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
654 current_alignement_constraints
= 1;
658 /* Note: we only check width here as you cannot have width non-zero while height is set to zero */
659 if (tex_width
== 0) {
662 tex_width
= surf_ptr
->surface_desc
.dwWidth
;
663 tex_height
= surf_ptr
->surface_desc
.dwHeight
;
666 current_tex_width
= tex_width
;
667 current_tex_height
= tex_height
;
669 if (src_pf
->dwFlags
& DDPF_PALETTEINDEXED8
) {
673 current_format
= GL_RGBA
;
674 internal_format
= GL_RGBA
;
675 current_pixel_format
= GL_UNSIGNED_BYTE
;
676 convert_type
= CONVERT_PALETTED
;
677 } else if (src_pf
->dwFlags
& DDPF_RGB
) {
681 if (src_pf
->u1
.dwRGBBitCount
== 8) {
682 if ((src_pf
->dwFlags
& DDPF_ALPHAPIXELS
) &&
683 (src_pf
->u5
.dwRGBAlphaBitMask
!= 0x00)) {
686 if ((src_pf
->u2
.dwRBitMask
== 0xE0) &&
687 (src_pf
->u3
.dwGBitMask
== 0x1C) &&
688 (src_pf
->u4
.dwBBitMask
== 0x03)) {
689 /* **********************
690 GL_UNSIGNED_BYTE_3_3_2
691 ********************** */
692 if (colorkey_active
) {
693 /* This texture format will never be used.. So do not care about color keying
694 up until the point in time it will be needed :-) */
695 FIXME(" ColorKeying not supported in the RGB 332 format !");
697 current_format
= GL_RGB
;
698 internal_format
= GL_RGB
;
699 current_pixel_format
= GL_UNSIGNED_BYTE_3_3_2
;
700 convert_type
= NO_CONVERSION
;
705 } else if (src_pf
->u1
.dwRGBBitCount
== 16) {
706 if ((src_pf
->dwFlags
& DDPF_ALPHAPIXELS
) &&
707 (src_pf
->u5
.dwRGBAlphaBitMask
!= 0x0000)) {
708 if ((src_pf
->u2
.dwRBitMask
== 0xF800) &&
709 (src_pf
->u3
.dwGBitMask
== 0x07C0) &&
710 (src_pf
->u4
.dwBBitMask
== 0x003E) &&
711 (src_pf
->u5
.dwRGBAlphaBitMask
== 0x0001)) {
712 current_format
= GL_RGBA
;
713 internal_format
= GL_RGBA
;
714 current_pixel_format
= GL_UNSIGNED_SHORT_5_5_5_1
;
715 if (colorkey_active
) {
716 convert_type
= CONVERT_CK_5551
;
718 convert_type
= NO_CONVERSION
;
720 } else if ((src_pf
->u2
.dwRBitMask
== 0xF000) &&
721 (src_pf
->u3
.dwGBitMask
== 0x0F00) &&
722 (src_pf
->u4
.dwBBitMask
== 0x00F0) &&
723 (src_pf
->u5
.dwRGBAlphaBitMask
== 0x000F)) {
724 current_format
= GL_RGBA
;
725 internal_format
= GL_RGBA
;
726 current_pixel_format
= GL_UNSIGNED_SHORT_4_4_4_4
;
727 if (colorkey_active
) {
728 convert_type
= CONVERT_CK_4444
;
730 convert_type
= NO_CONVERSION
;
732 } else if ((src_pf
->u2
.dwRBitMask
== 0x0F00) &&
733 (src_pf
->u3
.dwGBitMask
== 0x00F0) &&
734 (src_pf
->u4
.dwBBitMask
== 0x000F) &&
735 (src_pf
->u5
.dwRGBAlphaBitMask
== 0xF000)) {
736 if (colorkey_active
) {
737 convert_type
= CONVERT_CK_4444_ARGB
;
738 current_format
= GL_RGBA
;
739 internal_format
= GL_RGBA
;
740 current_pixel_format
= GL_UNSIGNED_SHORT_4_4_4_4
;
742 convert_type
= NO_CONVERSION
;
743 current_format
= GL_BGRA
;
744 internal_format
= GL_RGBA
;
745 current_pixel_format
= GL_UNSIGNED_SHORT_4_4_4_4_REV
;
747 } else if ((src_pf
->u2
.dwRBitMask
== 0x7C00) &&
748 (src_pf
->u3
.dwGBitMask
== 0x03E0) &&
749 (src_pf
->u4
.dwBBitMask
== 0x001F) &&
750 (src_pf
->u5
.dwRGBAlphaBitMask
== 0x8000)) {
751 if (colorkey_active
) {
752 convert_type
= CONVERT_CK_1555
;
753 current_format
= GL_RGBA
;
754 internal_format
= GL_RGBA
;
755 current_pixel_format
= GL_UNSIGNED_SHORT_5_5_5_1
;
757 convert_type
= NO_CONVERSION
;
758 current_format
= GL_BGRA
;
759 internal_format
= GL_RGBA
;
760 current_pixel_format
= GL_UNSIGNED_SHORT_1_5_5_5_REV
;
766 if ((src_pf
->u2
.dwRBitMask
== 0xF800) &&
767 (src_pf
->u3
.dwGBitMask
== 0x07E0) &&
768 (src_pf
->u4
.dwBBitMask
== 0x001F)) {
769 if (colorkey_active
) {
770 convert_type
= CONVERT_CK_565
;
771 current_format
= GL_RGBA
;
772 internal_format
= GL_RGBA
;
773 current_pixel_format
= GL_UNSIGNED_SHORT_5_5_5_1
;
775 convert_type
= NO_CONVERSION
;
776 current_format
= GL_RGB
;
777 internal_format
= GL_RGB
;
778 current_pixel_format
= GL_UNSIGNED_SHORT_5_6_5
;
780 } else if ((src_pf
->u2
.dwRBitMask
== 0x7C00) &&
781 (src_pf
->u3
.dwGBitMask
== 0x03E0) &&
782 (src_pf
->u4
.dwBBitMask
== 0x001F)) {
783 convert_type
= CONVERT_555
;
784 current_format
= GL_RGBA
;
785 internal_format
= GL_RGBA
;
786 current_pixel_format
= GL_UNSIGNED_SHORT_5_5_5_1
;
791 } else if (src_pf
->u1
.dwRGBBitCount
== 24) {
792 if ((src_pf
->dwFlags
& DDPF_ALPHAPIXELS
) &&
793 (src_pf
->u5
.dwRGBAlphaBitMask
!= 0x000000)) {
796 if ((src_pf
->u2
.dwRBitMask
== 0xFF0000) &&
797 (src_pf
->u3
.dwGBitMask
== 0x00FF00) &&
798 (src_pf
->u4
.dwBBitMask
== 0x0000FF)) {
799 if (colorkey_active
) {
800 convert_type
= CONVERT_CK_RGB24
;
801 current_format
= GL_RGBA
;
802 internal_format
= GL_RGBA
;
803 current_pixel_format
= GL_UNSIGNED_INT_8_8_8_8
;
805 convert_type
= NO_CONVERSION
;
806 current_format
= GL_BGR
;
807 internal_format
= GL_RGB
;
808 current_pixel_format
= GL_UNSIGNED_BYTE
;
814 } else if (src_pf
->u1
.dwRGBBitCount
== 32) {
815 if ((src_pf
->dwFlags
& DDPF_ALPHAPIXELS
) &&
816 (src_pf
->u5
.dwRGBAlphaBitMask
!= 0x00000000)) {
817 if ((src_pf
->u2
.dwRBitMask
== 0xFF000000) &&
818 (src_pf
->u3
.dwGBitMask
== 0x00FF0000) &&
819 (src_pf
->u4
.dwBBitMask
== 0x0000FF00) &&
820 (src_pf
->u5
.dwRGBAlphaBitMask
== 0x000000FF)) {
821 if (colorkey_active
) {
822 convert_type
= CONVERT_CK_8888
;
824 convert_type
= NO_CONVERSION
;
826 current_format
= GL_RGBA
;
827 internal_format
= GL_RGBA
;
828 current_pixel_format
= GL_UNSIGNED_INT_8_8_8_8
;
829 } else if ((src_pf
->u2
.dwRBitMask
== 0x00FF0000) &&
830 (src_pf
->u3
.dwGBitMask
== 0x0000FF00) &&
831 (src_pf
->u4
.dwBBitMask
== 0x000000FF) &&
832 (src_pf
->u5
.dwRGBAlphaBitMask
== 0xFF000000)) {
833 if (colorkey_active
) {
834 convert_type
= CONVERT_CK_8888_ARGB
;
835 current_format
= GL_RGBA
;
836 internal_format
= GL_RGBA
;
837 current_pixel_format
= GL_UNSIGNED_INT_8_8_8_8
;
839 convert_type
= NO_CONVERSION
;
840 current_format
= GL_BGRA
;
841 internal_format
= GL_RGBA
;
842 current_pixel_format
= GL_UNSIGNED_INT_8_8_8_8_REV
;
848 if ((src_pf
->u2
.dwRBitMask
== 0x00FF0000) &&
849 (src_pf
->u3
.dwGBitMask
== 0x0000FF00) &&
850 (src_pf
->u4
.dwBBitMask
== 0x000000FF)) {
851 if (need_alpha_ck
== TRUE
) {
852 convert_type
= CONVERT_RGB32_888
;
853 current_format
= GL_RGBA
;
854 internal_format
= GL_RGBA
;
855 current_pixel_format
= GL_UNSIGNED_INT_8_8_8_8
;
857 convert_type
= NO_CONVERSION
;
858 current_format
= GL_BGRA
;
859 internal_format
= GL_RGBA
;
860 current_pixel_format
= GL_UNSIGNED_INT_8_8_8_8_REV
;
874 ERR("Unsupported pixel format for textures : \n");
876 DDRAW_dump_pixelformat(src_pf
);
878 return DDERR_INVALIDPIXELFORMAT
;
880 if ((need_to_alloc
) ||
881 (internal_format
!= *current_internal_format
)) {
882 glTexImage2D(GL_TEXTURE_2D
, level
, internal_format
,
883 tex_width
, tex_height
, 0,
884 current_format
, current_pixel_format
, NULL
);
885 *current_internal_format
= internal_format
;
889 if ((sub_texture
== TRUE
) && (convert_type
== NO_CONVERSION
)) {
890 current_storage_width
= surf_ptr
->surface_desc
.u1
.lPitch
/ bpp
;
892 if (surf_ptr
->surface_desc
.u1
.lPitch
== (surf_ptr
->surface_desc
.dwWidth
* bpp
)) {
893 current_storage_width
= 0;
895 current_storage_width
= surf_ptr
->surface_desc
.u1
.lPitch
/ bpp
;
898 glPixelStorei(GL_UNPACK_ROW_LENGTH
, current_storage_width
);
903 HRESULT
upload_surface_to_tex_memory(RECT
*rect
, DWORD xoffset
, DWORD yoffset
, void **temp_buffer
)
905 const DDSURFACEDESC
* const src_d
= (DDSURFACEDESC
*)&(current_surface
->surface_desc
);
906 void *surf_buffer
= NULL
;
909 BYTE bpp
= GET_BPP(current_surface
->surface_desc
);
915 lrect
.bottom
= current_tex_height
;
916 lrect
.right
= current_tex_width
;
920 width
= rect
->right
- rect
->left
;
921 height
= rect
->bottom
- rect
->top
;
923 /* Used when converting stuff */
924 line_increase
= src_d
->u1
.lPitch
- (width
* bpp
);
926 switch (convert_type
) {
927 case CONVERT_PALETTED
: {
928 IDirectDrawPaletteImpl
* pal
= current_surface
->palette
;
932 BYTE
*src
= (BYTE
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
935 /* Upload a black texture. The real one will be uploaded on palette change */
936 WARN("Palettized texture Loading with a NULL palette !\n");
937 memset(table
, 0, 256 * 4);
939 /* Get the surface's palette */
940 for (i
= 0; i
< 256; i
++) {
941 table
[i
][0] = pal
->palents
[i
].peRed
;
942 table
[i
][1] = pal
->palents
[i
].peGreen
;
943 table
[i
][2] = pal
->palents
[i
].peBlue
;
944 if ((src_d
->dwFlags
& DDSD_CKSRCBLT
) &&
945 (i
>= src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) &&
946 (i
<= src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
947 /* We should maybe here put a more 'neutral' color than the standard bright purple
948 one often used by application to prevent the nice purple borders when bi-linear
956 if (*temp_buffer
== NULL
)
957 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
958 current_tex_width
* current_tex_height
* sizeof(DWORD
));
959 dst
= (BYTE
*) *temp_buffer
;
961 for (y
= 0; y
< height
; y
++) {
962 for (x
= 0; x
< width
; x
++) {
964 *dst
++ = table
[color
][0];
965 *dst
++ = table
[color
][1];
966 *dst
++ = table
[color
][2];
967 *dst
++ = table
[color
][3];
969 src
+= line_increase
;
973 case CONVERT_CK_565
: {
974 /* Converting the 565 format in 5551 packed to emulate color-keying.
976 Note : in all these conversion, it would be best to average the averaging
977 pixels to get the color of the pixel that will be color-keyed to
978 prevent 'color bleeding'. This will be done later on if ever it is
981 Note2: when using color-keying + alpha, are the alpha bits part of the
985 WORD
*src
= (WORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
987 if (*temp_buffer
== NULL
)
988 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
989 current_tex_width
* current_tex_height
* sizeof(WORD
));
990 dst
= (WORD
*) *temp_buffer
;
992 for (y
= 0; y
< height
; y
++) {
993 for (x
= 0; x
< width
; x
++) {
995 *dst
= ((color
& 0xFFD0) | ((color
& 0x1F) << 1));
996 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
997 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1001 src
= (WORD
*) (((BYTE
*) src
) + line_increase
);
1005 case CONVERT_CK_5551
: {
1006 /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
1008 WORD
*src
= (WORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1010 if (*temp_buffer
== NULL
)
1011 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1012 current_tex_width
* current_tex_height
* sizeof(WORD
));
1013 dst
= (WORD
*) *temp_buffer
;
1015 for (y
= 0; y
< height
; y
++) {
1016 for (x
= 0; x
< width
; x
++) {
1017 WORD color
= *src
++;
1018 *dst
= color
& 0xFFFE;
1019 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1020 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1021 *dst
|= color
& 0x0001;
1024 src
= (WORD
*) (((BYTE
*) src
) + line_increase
);
1028 case CONVERT_CK_4444
: {
1029 /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
1031 WORD
*src
= (WORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1033 if (*temp_buffer
== NULL
)
1034 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1035 current_tex_width
* current_tex_height
* sizeof(WORD
));
1036 dst
= (WORD
*) *temp_buffer
;
1038 for (y
= 0; y
< height
; y
++) {
1039 for (x
= 0; x
< width
; x
++) {
1040 WORD color
= *src
++;
1041 *dst
= color
& 0xFFF0;
1042 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1043 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1044 *dst
|= color
& 0x000F;
1047 src
= (WORD
*) (((BYTE
*) src
) + line_increase
);
1051 case CONVERT_CK_4444_ARGB
: {
1052 /* Move the four Alpha bits... */
1054 WORD
*src
= (WORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1056 if (*temp_buffer
== NULL
)
1057 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1058 current_tex_width
* current_tex_height
* sizeof(WORD
));
1059 dst
= (WORD
*) *temp_buffer
;
1061 for (y
= 0; y
< height
; y
++) {
1062 for (x
= 0; x
< width
; x
++) {
1063 WORD color
= *src
++;
1064 *dst
= (color
& 0x0FFF) << 4;
1065 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1066 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1067 *dst
|= (color
& 0xF000) >> 12;
1070 src
= (WORD
*) (((BYTE
*) src
) + line_increase
);
1074 case CONVERT_CK_1555
: {
1076 WORD
*src
= (WORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1078 if (*temp_buffer
== NULL
)
1079 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1080 current_tex_width
* current_tex_height
* sizeof(WORD
));
1081 dst
= (WORD
*) *temp_buffer
;
1083 for (y
= 0; y
< height
; y
++) {
1084 for (x
= 0; x
< width
; x
++) {
1085 WORD color
= *src
++;
1086 *dst
= (color
& 0x7FFF) << 1;
1087 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1088 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1089 *dst
|= (color
& 0x8000) >> 15;
1092 src
= (WORD
*) (((BYTE
*) src
) + line_increase
);
1097 /* Converting the 0555 format in 5551 packed */
1099 WORD
*src
= (WORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1101 if (*temp_buffer
== NULL
)
1102 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1103 current_tex_width
* current_tex_height
* sizeof(WORD
));
1104 dst
= (WORD
*) *temp_buffer
;
1106 if (src_d
->dwFlags
& DDSD_CKSRCBLT
) {
1107 for (y
= 0; y
< height
; y
++) {
1108 for (x
= 0; x
< width
; x
++) {
1109 WORD color
= *src
++;
1110 *dst
= (color
& 0x7FFF) << 1;
1111 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1112 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1116 src
= (WORD
*) (((BYTE
*) src
) + line_increase
);
1119 for (y
= 0; y
< height
; y
++) {
1120 for (x
= 0; x
< width
; x
++) {
1121 WORD color
= *src
++;
1122 *dst
++ = ((color
& 0x7FFF) << 1) | 0x0001;
1124 src
= (WORD
*) (((BYTE
*) src
) + line_increase
);
1130 case CONVERT_CK_RGB24
: {
1131 /* This is a pain :-) */
1133 BYTE
*src
= (BYTE
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
));
1136 if (*temp_buffer
== NULL
)
1137 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1138 current_tex_width
* current_tex_height
* sizeof(DWORD
));
1139 dst
= (DWORD
*) *temp_buffer
;
1141 for (y
= 0; y
< height
; y
++) {
1142 for (x
= 0; x
< width
; x
++) {
1143 DWORD color
= *((DWORD
*) src
) & 0x00FFFFFF;
1146 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1147 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1151 src
+= line_increase
;
1155 case CONVERT_CK_8888
: {
1156 /* Just use the alpha component to handle color-keying... */
1158 DWORD
*src
= (DWORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1160 if (*temp_buffer
== NULL
)
1161 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1162 current_tex_width
* current_tex_height
* sizeof(DWORD
));
1163 dst
= (DWORD
*) *temp_buffer
;
1165 for (y
= 0; y
< height
; y
++) {
1166 for (x
= 0; x
< width
; x
++) {
1167 DWORD color
= *src
++;
1168 *dst
= color
& 0xFFFFFF00;
1169 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1170 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1171 *dst
|= color
& 0x000000FF;
1174 src
= (DWORD
*) (((BYTE
*) src
) + line_increase
);
1178 case CONVERT_CK_8888_ARGB
: {
1180 DWORD
*src
= (DWORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1182 if (*temp_buffer
== NULL
)
1183 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1184 current_tex_width
* current_tex_height
* sizeof(DWORD
));
1185 dst
= (DWORD
*) *temp_buffer
;
1187 for (y
= 0; y
< height
; y
++) {
1188 for (x
= 0; x
< width
; x
++) {
1189 DWORD color
= *src
++;
1190 *dst
= (color
& 0x00FFFFFF) << 8;
1191 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1192 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1193 *dst
|= (color
& 0xFF000000) >> 24;
1196 src
= (DWORD
*) (((BYTE
*) src
) + line_increase
);
1200 case CONVERT_RGB32_888
: {
1201 /* Just add an alpha component and handle color-keying... */
1203 DWORD
*src
= (DWORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1205 if (*temp_buffer
== NULL
)
1206 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1207 current_tex_width
* current_tex_height
* sizeof(DWORD
));
1208 dst
= (DWORD
*) *temp_buffer
;
1210 if (src_d
->dwFlags
& DDSD_CKSRCBLT
) {
1211 for (y
= 0; y
< height
; y
++) {
1212 for (x
= 0; x
< width
; x
++) {
1213 DWORD color
= *src
++;
1215 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1216 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1220 src
= (DWORD
*) (((BYTE
*) src
) + line_increase
);
1223 for (y
= 0; y
< height
; y
++) {
1224 for (x
= 0; x
< width
; x
++) {
1225 *dst
++ = (*src
++ << 8) | 0xFF;
1227 src
= (DWORD
*) (((BYTE
*) src
) + line_increase
);
1233 /* Nothing to do here as the name suggests... Just set-up the buffer correctly */
1234 surf_buffer
= (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
));
1238 if (convert_type
!= NO_CONVERSION
) {
1239 /* When doing conversion, the storage is always of width 'width' as there will never
1240 be any Pitch issue... For now :-)
1242 surf_buffer
= *temp_buffer
;
1243 if (width
!= current_storage_width
) {
1244 glPixelStorei(GL_UNPACK_ROW_LENGTH
, width
);
1245 current_storage_width
= width
;
1249 glTexSubImage2D(GL_TEXTURE_2D
,
1254 current_pixel_format
,
1260 HRESULT
upload_surface_to_tex_memory_release(void)
1262 current_surface
= NULL
;