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
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
33 #include "wine/debug.h"
35 #include "mesa_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
39 GLenum
convert_D3D_compare_to_GL(D3DCMPFUNC dwRenderState
)
41 switch (dwRenderState
) {
42 case D3DCMP_NEVER
: return GL_NEVER
;
43 case D3DCMP_LESS
: return GL_LESS
;
44 case D3DCMP_EQUAL
: return GL_EQUAL
;
45 case D3DCMP_LESSEQUAL
: return GL_LEQUAL
;
46 case D3DCMP_GREATER
: return GL_GREATER
;
47 case D3DCMP_NOTEQUAL
: return GL_NOTEQUAL
;
48 case D3DCMP_GREATEREQUAL
: return GL_GEQUAL
;
49 case D3DCMP_ALWAYS
: return GL_ALWAYS
;
50 default: ERR("Unexpected compare type %d !\n", dwRenderState
);
55 GLenum
convert_D3D_stencilop_to_GL(D3DSTENCILOP dwRenderState
)
57 switch (dwRenderState
) {
58 case D3DSTENCILOP_KEEP
: return GL_KEEP
;
59 case D3DSTENCILOP_ZERO
: return GL_ZERO
;
60 case D3DSTENCILOP_REPLACE
: return GL_REPLACE
;
61 case D3DSTENCILOP_INCRSAT
: return GL_INCR
;
62 case D3DSTENCILOP_DECRSAT
: return GL_DECR
;
63 case D3DSTENCILOP_INVERT
: return GL_INVERT
;
64 case D3DSTENCILOP_INCR
: WARN("D3DSTENCILOP_INCR not properly handled !\n"); return GL_INCR
;
65 case D3DSTENCILOP_DECR
: WARN("D3DSTENCILOP_DECR not properly handled !\n"); return GL_DECR
;
66 default: ERR("Unexpected compare type %d !\n", dwRenderState
);
71 GLenum
convert_D3D_blendop_to_GL(D3DBLEND dwRenderState
)
73 switch ((D3DBLEND
) dwRenderState
) {
74 case D3DBLEND_ZERO
: return GL_ZERO
;
75 case D3DBLEND_ONE
: return GL_ONE
;
76 case D3DBLEND_SRCALPHA
: return GL_SRC_ALPHA
;
77 case D3DBLEND_INVSRCALPHA
: return GL_ONE_MINUS_SRC_ALPHA
;
78 case D3DBLEND_DESTALPHA
: return GL_DST_ALPHA
;
79 case D3DBLEND_INVDESTALPHA
: return GL_ONE_MINUS_DST_ALPHA
;
80 case D3DBLEND_DESTCOLOR
: return GL_DST_COLOR
;
81 case D3DBLEND_INVDESTCOLOR
: return GL_ONE_MINUS_DST_COLOR
;
82 case D3DBLEND_SRCALPHASAT
: return GL_SRC_ALPHA_SATURATE
;
83 case D3DBLEND_SRCCOLOR
: return GL_SRC_COLOR
;
84 case D3DBLEND_INVSRCCOLOR
: return GL_ONE_MINUS_SRC_COLOR
;
85 default: ERR("Unhandled blend mode %d !\n", dwRenderState
); return GL_ZERO
;
89 void set_render_state(IDirect3DDeviceImpl
* This
,
90 D3DRENDERSTATETYPE dwRenderStateType
, STATEBLOCK
*lpStateBlock
)
92 DWORD dwRenderState
= lpStateBlock
->render_state
[dwRenderStateType
- 1];
93 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
95 TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType
), dwRenderState
);
97 /* First, all the stipple patterns */
98 if ((dwRenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
) &&
99 (dwRenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)) {
100 ERR("Unhandled dwRenderStateType stipple %d!\n",dwRenderStateType
);
104 /* All others state variables */
105 switch (dwRenderStateType
) {
106 case D3DRENDERSTATE_TEXTUREHANDLE
: { /* 1 */
107 IDirectDrawSurfaceImpl
*tex
= (IDirectDrawSurfaceImpl
*) dwRenderState
;
109 IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This
, IDirect3DDevice7
),
111 ICOM_INTERFACE(tex
, IDirectDrawSurface7
));
114 case D3DRENDERSTATE_ANTIALIAS
: /* 2 */
116 ERR("D3DRENDERSTATE_ANTIALIAS not supported yet !\n");
119 case D3DRENDERSTATE_TEXTUREADDRESSU
: /* 44 */
120 case D3DRENDERSTATE_TEXTUREADDRESSV
: /* 45 */
121 case D3DRENDERSTATE_TEXTUREADDRESS
: { /* 3 */
122 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType
;
124 if (dwRenderStateType
== D3DRENDERSTATE_TEXTUREADDRESS
) d3dTexStageStateType
= D3DTSS_ADDRESS
;
125 else if (dwRenderStateType
== D3DRENDERSTATE_TEXTUREADDRESSU
) d3dTexStageStateType
= D3DTSS_ADDRESSU
;
126 else d3dTexStageStateType
= D3DTSS_ADDRESSV
;
128 IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This
, IDirect3DDevice7
),
129 0, d3dTexStageStateType
,
133 case D3DRENDERSTATE_TEXTUREPERSPECTIVE
: /* 4 */
135 glHint(GL_PERSPECTIVE_CORRECTION_HINT
, GL_NICEST
);
137 glHint(GL_PERSPECTIVE_CORRECTION_HINT
, GL_FASTEST
);
140 case D3DRENDERSTATE_WRAPU
: /* 5 */
141 case D3DRENDERSTATE_WRAPV
: /* 6 */
142 case D3DRENDERSTATE_WRAP0
: /* 128 */
143 case D3DRENDERSTATE_WRAP1
: /* 129 */
144 case D3DRENDERSTATE_WRAP2
: /* 130 */
145 case D3DRENDERSTATE_WRAP3
: /* 131 */
146 case D3DRENDERSTATE_WRAP4
: /* 132 */
147 case D3DRENDERSTATE_WRAP5
: /* 133 */
148 case D3DRENDERSTATE_WRAP6
: /* 134 */
149 case D3DRENDERSTATE_WRAP7
: /* 135 */
151 ERR("Texture WRAP modes unsupported by OpenGL.. Expect graphical glitches !\n");
154 case D3DRENDERSTATE_ZENABLE
: /* 7 */
155 /* To investigate : in OpenGL, if we disable the depth test, the Z buffer will NOT be
156 updated either.. No idea about what happens in D3D.
158 Maybe replacing the Z function by ALWAYS would be a better idea. */
159 if (dwRenderState
== D3DZB_TRUE
) {
160 if (glThis
->depth_test
== FALSE
) {
161 glEnable(GL_DEPTH_TEST
);
162 glThis
->depth_test
= TRUE
;
164 } else if (dwRenderState
== D3DZB_FALSE
) {
165 if (glThis
->depth_test
) {
166 glDisable(GL_DEPTH_TEST
);
167 glThis
->depth_test
= FALSE
;
170 if (glThis
->depth_test
== FALSE
) {
171 glEnable(GL_DEPTH_TEST
);
172 glThis
->depth_test
= TRUE
;
174 WARN(" w-buffering not supported.\n");
178 case D3DRENDERSTATE_FILLMODE
: /* 8 */
179 switch ((D3DFILLMODE
) dwRenderState
) {
181 glPolygonMode(GL_FRONT_AND_BACK
,GL_POINT
);
183 case D3DFILL_WIREFRAME
:
184 glPolygonMode(GL_FRONT_AND_BACK
,GL_LINE
);
187 glPolygonMode(GL_FRONT_AND_BACK
,GL_FILL
);
190 ERR("Unhandled fill mode %ld !\n",dwRenderState
);
194 case D3DRENDERSTATE_SHADEMODE
: /* 9 */
195 switch ((D3DSHADEMODE
) dwRenderState
) {
197 glShadeModel(GL_FLAT
);
199 case D3DSHADE_GOURAUD
:
200 glShadeModel(GL_SMOOTH
);
203 ERR("Unhandled shade mode %ld !\n",dwRenderState
);
207 case D3DRENDERSTATE_ZWRITEENABLE
: /* 14 */
208 if ((dwRenderState
!= FALSE
) && (glThis
->depth_mask
== FALSE
))
209 glDepthMask(GL_TRUE
);
210 else if ((dwRenderState
== FALSE
) && (glThis
->depth_mask
!= FALSE
))
211 glDepthMask(GL_FALSE
);
212 glThis
->depth_mask
= dwRenderState
;
215 case D3DRENDERSTATE_ALPHATESTENABLE
: /* 15 */
216 if ((dwRenderState
!= 0) && (glThis
->alpha_test
== FALSE
))
217 glEnable(GL_ALPHA_TEST
);
218 else if ((dwRenderState
== 0) && (glThis
->alpha_test
!= FALSE
))
219 glDisable(GL_ALPHA_TEST
);
220 glThis
->alpha_test
= dwRenderState
;
223 case D3DRENDERSTATE_TEXTUREMAG
: { /* 17 */
224 DWORD tex_mag
= 0xFFFFFFFF;
226 switch ((D3DTEXTUREFILTER
) dwRenderState
) {
227 case D3DFILTER_NEAREST
:
228 tex_mag
= D3DTFG_POINT
;
230 case D3DFILTER_LINEAR
:
231 tex_mag
= D3DTFG_LINEAR
;
234 ERR("Unhandled texture mag %ld !\n",dwRenderState
);
237 if (tex_mag
!= 0xFFFFFFFF) {
238 IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This
, IDirect3DDevice7
), 0, D3DTSS_MAGFILTER
, tex_mag
);
242 case D3DRENDERSTATE_TEXTUREMIN
: { /* 18 */
243 DWORD tex_min
= 0xFFFFFFFF;
245 switch ((D3DTEXTUREFILTER
) dwRenderState
) {
246 case D3DFILTER_NEAREST
:
247 tex_min
= D3DTFN_POINT
;
249 case D3DFILTER_LINEAR
:
250 tex_min
= D3DTFN_LINEAR
;
253 ERR("Unhandled texture min %ld !\n",dwRenderState
);
256 if (tex_min
!= 0xFFFFFFFF) {
257 IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This
, IDirect3DDevice7
), 0, D3DTSS_MINFILTER
, tex_min
);
261 case D3DRENDERSTATE_SRCBLEND
: /* 19 */
262 case D3DRENDERSTATE_DESTBLEND
: /* 20 */
263 glBlendFunc(convert_D3D_blendop_to_GL(lpStateBlock
->render_state
[D3DRENDERSTATE_SRCBLEND
- 1]),
264 convert_D3D_blendop_to_GL(lpStateBlock
->render_state
[D3DRENDERSTATE_DESTBLEND
- 1]));
267 case D3DRENDERSTATE_TEXTUREMAPBLEND
: { /* 21 */
268 IDirect3DDevice7
*d3ddev
= ICOM_INTERFACE(This
, IDirect3DDevice7
);
270 switch ((D3DTEXTUREBLEND
) dwRenderState
) {
271 case D3DTBLEND_DECAL
:
272 if (glThis
->current_tex_env
!= GL_REPLACE
) {
273 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
274 glThis
->current_tex_env
= GL_REPLACE
;
277 case D3DTBLEND_DECALALPHA
:
278 if (glThis
->current_tex_env
!= GL_REPLACE
) {
279 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_DECAL
);
280 glThis
->current_tex_env
= GL_DECAL
;
283 case D3DTBLEND_MODULATE
:
284 if (glThis
->current_tex_env
!= GL_MODULATE
) {
285 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
286 glThis
->current_tex_env
= GL_MODULATE
;
289 case D3DTBLEND_MODULATEALPHA
:
290 IDirect3DDevice7_SetTextureStageState(d3ddev
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
291 IDirect3DDevice7_SetTextureStageState(d3ddev
, 0, D3DTSS_ALPHAARG1
, D3DTA_TEXTURE
);
292 IDirect3DDevice7_SetTextureStageState(d3ddev
, 0, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
293 IDirect3DDevice7_SetTextureStageState(d3ddev
, 0, D3DTSS_ALPHAARG2
, D3DTA_CURRENT
);
294 IDirect3DDevice7_SetTextureStageState(d3ddev
, 0, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
295 IDirect3DDevice7_SetTextureStageState(d3ddev
, 0, D3DTSS_ALPHAOP
, D3DTOP_MODULATE
);
298 ERR("Unhandled texture environment %ld !\n",dwRenderState
);
302 case D3DRENDERSTATE_CULLMODE
: /* 22 */
303 switch ((D3DCULL
) dwRenderState
) {
305 if (glThis
->cull_face
!= 0) {
306 glDisable(GL_CULL_FACE
);
307 glThis
->cull_face
= 0;
311 if (glThis
->cull_face
== 0) {
312 glEnable(GL_CULL_FACE
);
313 glThis
->cull_face
= 1;
319 if (glThis
->cull_face
== 0) {
320 glEnable(GL_CULL_FACE
);
321 glThis
->cull_face
= 1;
327 ERR("Unhandled cull mode %ld !\n",dwRenderState
);
331 case D3DRENDERSTATE_ZFUNC
: /* 23 */
332 glDepthFunc(convert_D3D_compare_to_GL(dwRenderState
));
335 case D3DRENDERSTATE_ALPHAREF
: /* 24 */
336 case D3DRENDERSTATE_ALPHAFUNC
: { /* 25 */
337 GLenum func
= convert_D3D_compare_to_GL(lpStateBlock
->render_state
[D3DRENDERSTATE_ALPHAFUNC
- 1]);
338 GLclampf ref
= (lpStateBlock
->render_state
[D3DRENDERSTATE_ALPHAREF
- 1] & 0x000000FF) / 255.0;
340 if ((func
!= glThis
->current_alpha_test_func
) || (ref
!= glThis
->current_alpha_test_ref
)) {
341 glAlphaFunc(func
, ref
);
342 glThis
->current_alpha_test_func
= func
;
343 glThis
->current_alpha_test_ref
= ref
;
348 case D3DRENDERSTATE_DITHERENABLE
: /* 26 */
352 glDisable(GL_DITHER
);
355 case D3DRENDERSTATE_ALPHABLENDENABLE
: /* 27 */
356 if ((dwRenderState
!= 0) && (glThis
->blending
== 0)) {
358 } else if ((dwRenderState
== 0) && (glThis
->blending
!= 0)) {
361 glThis
->blending
= dwRenderState
;
363 /* Hack for some old games ... */
364 if (glThis
->version
== 1) {
365 lpStateBlock
->render_state
[D3DRENDERSTATE_COLORKEYENABLE
- 1] = dwRenderState
;
369 case D3DRENDERSTATE_FOGENABLE
: /* 28 */
370 /* Nothing to do here. Only the storage matters :-) */
373 case D3DRENDERSTATE_SPECULARENABLE
: /* 29 */
375 ERR(" Specular Lighting not supported yet.\n");
378 case D3DRENDERSTATE_SUBPIXEL
: /* 31 */
379 case D3DRENDERSTATE_SUBPIXELX
: /* 32 */
380 /* We do not support this anyway, so why protest :-) */
383 case D3DRENDERSTATE_STIPPLEDALPHA
: /* 33 */
385 ERR(" Stippled Alpha not supported yet.\n");
388 case D3DRENDERSTATE_FOGCOLOR
: { /* 34 */
390 color
[0] = ((dwRenderState
>> 16) & 0xFF)/255.0f
;
391 color
[1] = ((dwRenderState
>> 8) & 0xFF)/255.0f
;
392 color
[2] = ((dwRenderState
>> 0) & 0xFF)/255.0f
;
393 color
[3] = ((dwRenderState
>> 24) & 0xFF)/255.0f
;
394 glFogfv(GL_FOG_COLOR
,color
);
395 /* Note: glFogiv does not seem to work */
398 case D3DRENDERSTATE_FOGTABLEMODE
: /* 35 */
399 case D3DRENDERSTATE_FOGVERTEXMODE
: /* 140 */
400 case D3DRENDERSTATE_FOGSTART
: /* 36 */
401 case D3DRENDERSTATE_FOGEND
: /* 37 */
402 /* Nothing to do here. Only the storage matters :-) */
405 case D3DRENDERSTATE_FOGDENSITY
: /* 38 */
406 glFogi(GL_FOG_DENSITY
,*(float*)&dwRenderState
);
409 case D3DRENDERSTATE_COLORKEYENABLE
: /* 41 */
410 /* Nothing done here, only storage matters. */
413 case D3DRENDERSTATE_MIPMAPLODBIAS
: /* 46 */
414 IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This
, IDirect3DDevice7
),
415 0, D3DTSS_MIPMAPLODBIAS
,
419 case D3DRENDERSTATE_ZBIAS
: /* 47 */
420 /* This is a tad bit hacky.. But well, no idea how to do it better in OpenGL :-/ */
421 if (dwRenderState
== 0) {
422 glDisable(GL_POLYGON_OFFSET_FILL
);
423 glDisable(GL_POLYGON_OFFSET_LINE
);
424 glDisable(GL_POLYGON_OFFSET_POINT
);
426 glEnable(GL_POLYGON_OFFSET_FILL
);
427 glEnable(GL_POLYGON_OFFSET_LINE
);
428 glEnable(GL_POLYGON_OFFSET_POINT
);
429 glPolygonOffset(1.0, dwRenderState
* 1.0);
433 case D3DRENDERSTATE_FLUSHBATCH
: /* 50 */
436 case D3DRENDERSTATE_STENCILENABLE
: /* 52 */
437 if ((dwRenderState
!= 0) && (glThis
->stencil_test
== 0))
438 glEnable(GL_STENCIL_TEST
);
439 else if ((dwRenderState
== 0) && (glThis
->stencil_test
!= 0))
440 glDisable(GL_STENCIL_TEST
);
441 glThis
->stencil_test
= dwRenderState
;
444 case D3DRENDERSTATE_STENCILFAIL
: /* 53 */
445 case D3DRENDERSTATE_STENCILZFAIL
: /* 54 */
446 case D3DRENDERSTATE_STENCILPASS
: /* 55 */
447 glStencilOp(convert_D3D_stencilop_to_GL(lpStateBlock
->render_state
[D3DRENDERSTATE_STENCILFAIL
- 1]),
448 convert_D3D_stencilop_to_GL(lpStateBlock
->render_state
[D3DRENDERSTATE_STENCILZFAIL
- 1]),
449 convert_D3D_stencilop_to_GL(lpStateBlock
->render_state
[D3DRENDERSTATE_STENCILPASS
- 1]));
452 case D3DRENDERSTATE_STENCILFUNC
: /* 56 */
453 case D3DRENDERSTATE_STENCILREF
: /* 57 */
454 case D3DRENDERSTATE_STENCILMASK
: /* 58 */
455 glStencilFunc(convert_D3D_compare_to_GL(lpStateBlock
->render_state
[D3DRENDERSTATE_STENCILFUNC
- 1]),
456 lpStateBlock
->render_state
[D3DRENDERSTATE_STENCILREF
- 1],
457 lpStateBlock
->render_state
[D3DRENDERSTATE_STENCILMASK
- 1]);
460 case D3DRENDERSTATE_STENCILWRITEMASK
: /* 59 */
461 glStencilMask(dwRenderState
);
464 case D3DRENDERSTATE_TEXTUREFACTOR
: /* 60 */
465 /* Only the storage matters... */
468 case D3DRENDERSTATE_CLIPPING
: /* 136 */
469 case D3DRENDERSTATE_CLIPPLANEENABLE
: { /* 152 */
473 if (dwRenderStateType
== D3DRENDERSTATE_CLIPPING
) {
474 mask
= ((dwRenderState
) ?
475 (This
->state_block
.render_state
[D3DRENDERSTATE_CLIPPLANEENABLE
- 1]) : (0x00000000));
477 mask
= dwRenderState
;
479 for (i
= 0, runner
= 0x00000001; i
< This
->max_clipping_planes
; i
++, runner
= (runner
<< 1)) {
482 glGetIntegerv(GL_CLIP_PLANE0
+ i
, &enabled
);
483 if (enabled
== GL_FALSE
) {
484 glEnable(GL_CLIP_PLANE0
+ i
);
485 /* Need to force a transform change so that this clipping plane parameters are sent
488 glThis
->transform_state
= GL_TRANSFORM_NONE
;
491 glDisable(GL_CLIP_PLANE0
+ i
);
497 case D3DRENDERSTATE_LIGHTING
: /* 137 */
498 /* Nothing to do, only storage matters... */
501 case D3DRENDERSTATE_AMBIENT
: { /* 139 */
504 light
[0] = ((dwRenderState
>> 16) & 0xFF) / 255.0;
505 light
[1] = ((dwRenderState
>> 8) & 0xFF) / 255.0;
506 light
[2] = ((dwRenderState
>> 0) & 0xFF) / 255.0;
507 light
[3] = ((dwRenderState
>> 24) & 0xFF) / 255.0;
508 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, (float *) light
);
511 case D3DRENDERSTATE_COLORVERTEX
: /* 141 */
512 /* Nothing to do here.. Only storage matters */
515 case D3DRENDERSTATE_LOCALVIEWER
: /* 142 */
517 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER
, GL_TRUE
);
519 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER
, GL_FALSE
);
522 case D3DRENDERSTATE_NORMALIZENORMALS
: /* 143 */
524 glEnable(GL_NORMALIZE
);
525 glEnable(GL_RESCALE_NORMAL
);
527 glDisable(GL_NORMALIZE
);
528 glDisable(GL_RESCALE_NORMAL
);
532 case D3DRENDERSTATE_DIFFUSEMATERIALSOURCE
: /* 145 */
533 case D3DRENDERSTATE_SPECULARMATERIALSOURCE
: /* 146 */
534 case D3DRENDERSTATE_AMBIENTMATERIALSOURCE
: /* 147 */
535 case D3DRENDERSTATE_EMISSIVEMATERIALSOURCE
: /* 148 */
536 /* Nothing to do here. Only the storage matters :-) */
540 ERR("Unhandled dwRenderStateType %s (%08x) value : %08lx !\n",
541 _get_renderstate(dwRenderStateType
), dwRenderStateType
, dwRenderState
);
547 void store_render_state(IDirect3DDeviceImpl
*This
,
548 D3DRENDERSTATETYPE dwRenderStateType
, DWORD dwRenderState
, STATEBLOCK
*lpStateBlock
)
550 TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType
), dwRenderState
);
552 /* Some special cases first.. */
553 if (dwRenderStateType
== D3DRENDERSTATE_SRCBLEND
) {
554 if (dwRenderState
== D3DBLEND_BOTHSRCALPHA
) {
555 lpStateBlock
->render_state
[D3DRENDERSTATE_SRCBLEND
- 1] = D3DBLEND_SRCALPHA
;
556 lpStateBlock
->render_state
[D3DRENDERSTATE_DESTBLEND
- 1] = D3DBLEND_INVSRCALPHA
;
558 } else if (dwRenderState
== D3DBLEND_BOTHINVSRCALPHA
) {
559 lpStateBlock
->render_state
[D3DRENDERSTATE_SRCBLEND
- 1] = D3DBLEND_INVSRCALPHA
;
560 lpStateBlock
->render_state
[D3DRENDERSTATE_DESTBLEND
- 1] = D3DBLEND_SRCALPHA
;
563 } else if (dwRenderStateType
== D3DRENDERSTATE_TEXTUREADDRESS
) {
564 lpStateBlock
->render_state
[D3DRENDERSTATE_TEXTUREADDRESSU
- 1] = dwRenderState
;
565 lpStateBlock
->render_state
[D3DRENDERSTATE_TEXTUREADDRESSV
- 1] = dwRenderState
;
566 } else if (dwRenderStateType
== D3DRENDERSTATE_WRAPU
) {
568 lpStateBlock
->render_state
[D3DRENDERSTATE_WRAP0
] |= D3DWRAP_U
;
570 lpStateBlock
->render_state
[D3DRENDERSTATE_WRAP0
] &= ~D3DWRAP_U
;
571 } else if (dwRenderStateType
== D3DRENDERSTATE_WRAPV
) {
573 lpStateBlock
->render_state
[D3DRENDERSTATE_WRAP0
] |= D3DWRAP_V
;
575 lpStateBlock
->render_state
[D3DRENDERSTATE_WRAP0
] &= ~D3DWRAP_V
;
579 lpStateBlock
->render_state
[dwRenderStateType
- 1] = dwRenderState
;
582 void get_render_state(IDirect3DDeviceImpl
*This
,
583 D3DRENDERSTATETYPE dwRenderStateType
, LPDWORD lpdwRenderState
, STATEBLOCK
*lpStateBlock
)
585 *lpdwRenderState
= lpStateBlock
->render_state
[dwRenderStateType
- 1];
587 TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType
), *lpdwRenderState
);
590 void apply_render_state(IDirect3DDeviceImpl
*This
, STATEBLOCK
*lpStateBlock
)
593 TRACE("(%p,%p)\n", This
, lpStateBlock
);
594 for(i
= 0; i
< HIGHEST_RENDER_STATE
; i
++)
595 if (lpStateBlock
->set_flags
.render_state
[i
])
596 set_render_state(This
, i
+ 1, lpStateBlock
);
600 /* Texture management code.
602 - upload_surface_to_tex_memory_init initialize the code and computes the GL formats
603 according to the surface description.
605 - upload_surface_to_tex_memory does the real upload. If one buffer is split over
606 multiple textures, this can be called multiple times after the '_init' call. 'rect'
607 can be NULL if the whole buffer needs to be upload.
609 - upload_surface_to_tex_memory_release does the clean-up.
611 These functions are called in the following cases :
612 - texture management (ie to upload a D3D texture to GL when it changes).
613 - flush of the 'in-memory' frame buffer to the GL frame buffer using the texture
615 - use of the texture engine to simulate Blits to the 3D Device.
623 CONVERT_CK_4444_ARGB
,
628 CONVERT_CK_8888_ARGB
,
632 /* Note : we suppose that all the code calling this is protected by the GL lock... Otherwise bad things
634 static GLenum current_format
;
635 static GLenum current_pixel_format
;
636 static CONVERT_TYPES convert_type
;
637 static IDirectDrawSurfaceImpl
*current_surface
;
638 static GLuint current_level
;
639 static DWORD current_tex_width
;
640 static DWORD current_tex_height
;
641 static GLuint current_alignement_constraints
;
642 static int current_storage_width
;
644 HRESULT
upload_surface_to_tex_memory_init(IDirectDrawSurfaceImpl
*surf_ptr
, GLuint level
, GLenum
*current_internal_format
,
645 BOOLEAN need_to_alloc
, BOOLEAN need_alpha_ck
, DWORD tex_width
, DWORD tex_height
)
647 const DDPIXELFORMAT
* const src_pf
= &(surf_ptr
->surface_desc
.u4
.ddpfPixelFormat
);
649 BOOL colorkey_active
= need_alpha_ck
&& (surf_ptr
->surface_desc
.dwFlags
& DDSD_CKSRCBLT
);
650 GLenum internal_format
= GL_LUMINANCE
; /* A bogus value to be sure to have a nice Mesa warning :-) */
651 BYTE bpp
= GET_BPP(surf_ptr
->surface_desc
);
652 BOOL sub_texture
= TRUE
;
654 current_surface
= surf_ptr
;
655 current_level
= level
;
657 if (src_pf
->dwFlags
& DDPF_FOURCC
) {
659 int size
= surf_ptr
->surface_desc
.u1
.dwLinearSize
;
660 int width
= surf_ptr
->surface_desc
.dwWidth
;
661 int height
= surf_ptr
->surface_desc
.dwHeight
;
662 LPVOID buffer
= surf_ptr
->surface_desc
.lpSurface
;
664 switch (src_pf
->dwFourCC
) {
665 case MAKE_FOURCC('D','X','T','1'): retVal
= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
; break;
666 case MAKE_FOURCC('D','X','T','3'): retVal
= GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
; break;
667 case MAKE_FOURCC('D','X','T','5'): retVal
= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
; break;
669 FIXME("FourCC Not supported\n");
674 if (GL_extensions
.s3tc_compressed_texture
) {
675 GL_extensions
.glCompressedTexImage2D(GL_TEXTURE_2D
, current_level
, retVal
, width
, height
, 0, size
, buffer
);
677 ERR("Trying to upload S3TC texture whereas the device does not have support for it\n");
682 /* First, do some sanity checks ... */
683 if ((surf_ptr
->surface_desc
.u1
.lPitch
% bpp
) != 0) {
684 FIXME("Warning : pitch is not a multiple of BPP - not supported yet !\n");
686 /* In that case, no need to have any alignement constraints... */
687 if (current_alignement_constraints
!= 1) {
688 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
689 current_alignement_constraints
= 1;
693 /* Note: we only check width here as you cannot have width non-zero while height is set to zero */
694 if (tex_width
== 0) {
697 tex_width
= surf_ptr
->surface_desc
.dwWidth
;
698 tex_height
= surf_ptr
->surface_desc
.dwHeight
;
701 current_tex_width
= tex_width
;
702 current_tex_height
= tex_height
;
704 if (src_pf
->dwFlags
& DDPF_PALETTEINDEXED8
) {
708 current_format
= GL_RGBA
;
709 internal_format
= GL_RGBA
;
710 current_pixel_format
= GL_UNSIGNED_BYTE
;
711 convert_type
= CONVERT_PALETTED
;
712 } else if (src_pf
->dwFlags
& DDPF_RGB
) {
716 if (src_pf
->u1
.dwRGBBitCount
== 8) {
717 if ((src_pf
->dwFlags
& DDPF_ALPHAPIXELS
) &&
718 (src_pf
->u5
.dwRGBAlphaBitMask
!= 0x00)) {
721 if ((src_pf
->u2
.dwRBitMask
== 0xE0) &&
722 (src_pf
->u3
.dwGBitMask
== 0x1C) &&
723 (src_pf
->u4
.dwBBitMask
== 0x03)) {
724 /* **********************
725 GL_UNSIGNED_BYTE_3_3_2
726 ********************** */
727 if (colorkey_active
) {
728 /* This texture format will never be used.. So do not care about color keying
729 up until the point in time it will be needed :-) */
730 FIXME(" ColorKeying not supported in the RGB 332 format !\n");
732 current_format
= GL_RGB
;
733 internal_format
= GL_RGB
;
734 current_pixel_format
= GL_UNSIGNED_BYTE_3_3_2
;
735 convert_type
= NO_CONVERSION
;
740 } else if (src_pf
->u1
.dwRGBBitCount
== 16) {
741 if ((src_pf
->dwFlags
& DDPF_ALPHAPIXELS
) &&
742 (src_pf
->u5
.dwRGBAlphaBitMask
!= 0x0000)) {
743 if ((src_pf
->u2
.dwRBitMask
== 0xF800) &&
744 (src_pf
->u3
.dwGBitMask
== 0x07C0) &&
745 (src_pf
->u4
.dwBBitMask
== 0x003E) &&
746 (src_pf
->u5
.dwRGBAlphaBitMask
== 0x0001)) {
747 current_format
= GL_RGBA
;
748 internal_format
= GL_RGBA
;
749 current_pixel_format
= GL_UNSIGNED_SHORT_5_5_5_1
;
750 if (colorkey_active
) {
751 convert_type
= CONVERT_CK_5551
;
753 convert_type
= NO_CONVERSION
;
755 } else if ((src_pf
->u2
.dwRBitMask
== 0xF000) &&
756 (src_pf
->u3
.dwGBitMask
== 0x0F00) &&
757 (src_pf
->u4
.dwBBitMask
== 0x00F0) &&
758 (src_pf
->u5
.dwRGBAlphaBitMask
== 0x000F)) {
759 current_format
= GL_RGBA
;
760 internal_format
= GL_RGBA
;
761 current_pixel_format
= GL_UNSIGNED_SHORT_4_4_4_4
;
762 if (colorkey_active
) {
763 convert_type
= CONVERT_CK_4444
;
765 convert_type
= NO_CONVERSION
;
767 } else if ((src_pf
->u2
.dwRBitMask
== 0x0F00) &&
768 (src_pf
->u3
.dwGBitMask
== 0x00F0) &&
769 (src_pf
->u4
.dwBBitMask
== 0x000F) &&
770 (src_pf
->u5
.dwRGBAlphaBitMask
== 0xF000)) {
771 if (colorkey_active
) {
772 convert_type
= CONVERT_CK_4444_ARGB
;
773 current_format
= GL_RGBA
;
774 internal_format
= GL_RGBA
;
775 current_pixel_format
= GL_UNSIGNED_SHORT_4_4_4_4
;
777 convert_type
= NO_CONVERSION
;
778 current_format
= GL_BGRA
;
779 internal_format
= GL_RGBA
;
780 current_pixel_format
= GL_UNSIGNED_SHORT_4_4_4_4_REV
;
782 } else if ((src_pf
->u2
.dwRBitMask
== 0x7C00) &&
783 (src_pf
->u3
.dwGBitMask
== 0x03E0) &&
784 (src_pf
->u4
.dwBBitMask
== 0x001F) &&
785 (src_pf
->u5
.dwRGBAlphaBitMask
== 0x8000)) {
786 if (colorkey_active
) {
787 convert_type
= CONVERT_CK_1555
;
788 current_format
= GL_RGBA
;
789 internal_format
= GL_RGBA
;
790 current_pixel_format
= GL_UNSIGNED_SHORT_5_5_5_1
;
792 convert_type
= NO_CONVERSION
;
793 current_format
= GL_BGRA
;
794 internal_format
= GL_RGBA
;
795 current_pixel_format
= GL_UNSIGNED_SHORT_1_5_5_5_REV
;
801 if ((src_pf
->u2
.dwRBitMask
== 0xF800) &&
802 (src_pf
->u3
.dwGBitMask
== 0x07E0) &&
803 (src_pf
->u4
.dwBBitMask
== 0x001F)) {
804 if (colorkey_active
) {
805 convert_type
= CONVERT_CK_565
;
806 current_format
= GL_RGBA
;
807 internal_format
= GL_RGBA
;
808 current_pixel_format
= GL_UNSIGNED_SHORT_5_5_5_1
;
810 convert_type
= NO_CONVERSION
;
811 current_format
= GL_RGB
;
812 internal_format
= GL_RGB
;
813 current_pixel_format
= GL_UNSIGNED_SHORT_5_6_5
;
815 } else if ((src_pf
->u2
.dwRBitMask
== 0x7C00) &&
816 (src_pf
->u3
.dwGBitMask
== 0x03E0) &&
817 (src_pf
->u4
.dwBBitMask
== 0x001F)) {
818 convert_type
= CONVERT_555
;
819 current_format
= GL_RGBA
;
820 internal_format
= GL_RGBA
;
821 current_pixel_format
= GL_UNSIGNED_SHORT_5_5_5_1
;
826 } else if (src_pf
->u1
.dwRGBBitCount
== 24) {
827 if ((src_pf
->dwFlags
& DDPF_ALPHAPIXELS
) &&
828 (src_pf
->u5
.dwRGBAlphaBitMask
!= 0x000000)) {
831 if ((src_pf
->u2
.dwRBitMask
== 0xFF0000) &&
832 (src_pf
->u3
.dwGBitMask
== 0x00FF00) &&
833 (src_pf
->u4
.dwBBitMask
== 0x0000FF)) {
834 if (colorkey_active
) {
835 convert_type
= CONVERT_CK_RGB24
;
836 current_format
= GL_RGBA
;
837 internal_format
= GL_RGBA
;
838 current_pixel_format
= GL_UNSIGNED_INT_8_8_8_8
;
840 convert_type
= NO_CONVERSION
;
841 current_format
= GL_BGR
;
842 internal_format
= GL_RGB
;
843 current_pixel_format
= GL_UNSIGNED_BYTE
;
849 } else if (src_pf
->u1
.dwRGBBitCount
== 32) {
850 if ((src_pf
->dwFlags
& DDPF_ALPHAPIXELS
) &&
851 (src_pf
->u5
.dwRGBAlphaBitMask
!= 0x00000000)) {
852 if ((src_pf
->u2
.dwRBitMask
== 0xFF000000) &&
853 (src_pf
->u3
.dwGBitMask
== 0x00FF0000) &&
854 (src_pf
->u4
.dwBBitMask
== 0x0000FF00) &&
855 (src_pf
->u5
.dwRGBAlphaBitMask
== 0x000000FF)) {
856 if (colorkey_active
) {
857 convert_type
= CONVERT_CK_8888
;
859 convert_type
= NO_CONVERSION
;
861 current_format
= GL_RGBA
;
862 internal_format
= GL_RGBA
;
863 current_pixel_format
= GL_UNSIGNED_INT_8_8_8_8
;
864 } else if ((src_pf
->u2
.dwRBitMask
== 0x00FF0000) &&
865 (src_pf
->u3
.dwGBitMask
== 0x0000FF00) &&
866 (src_pf
->u4
.dwBBitMask
== 0x000000FF) &&
867 (src_pf
->u5
.dwRGBAlphaBitMask
== 0xFF000000)) {
868 if (colorkey_active
) {
869 convert_type
= CONVERT_CK_8888_ARGB
;
870 current_format
= GL_RGBA
;
871 internal_format
= GL_RGBA
;
872 current_pixel_format
= GL_UNSIGNED_INT_8_8_8_8
;
874 convert_type
= NO_CONVERSION
;
875 current_format
= GL_BGRA
;
876 internal_format
= GL_RGBA
;
877 current_pixel_format
= GL_UNSIGNED_INT_8_8_8_8_REV
;
883 if ((src_pf
->u2
.dwRBitMask
== 0x00FF0000) &&
884 (src_pf
->u3
.dwGBitMask
== 0x0000FF00) &&
885 (src_pf
->u4
.dwBBitMask
== 0x000000FF)) {
887 convert_type
= CONVERT_RGB32_888
;
888 current_format
= GL_RGBA
;
889 internal_format
= GL_RGBA
;
890 current_pixel_format
= GL_UNSIGNED_INT_8_8_8_8
;
892 convert_type
= NO_CONVERSION
;
893 current_format
= GL_BGRA
;
894 internal_format
= GL_RGBA
;
895 current_pixel_format
= GL_UNSIGNED_INT_8_8_8_8_REV
;
909 ERR("Unsupported pixel format for textures : \n");
911 DDRAW_dump_pixelformat(src_pf
);
913 return DDERR_INVALIDPIXELFORMAT
;
915 if ((need_to_alloc
) ||
916 (internal_format
!= *current_internal_format
)) {
917 glTexImage2D(GL_TEXTURE_2D
, level
, internal_format
,
918 tex_width
, tex_height
, 0,
919 current_format
, current_pixel_format
, NULL
);
920 *current_internal_format
= internal_format
;
924 if (sub_texture
&& (convert_type
== NO_CONVERSION
)) {
925 current_storage_width
= surf_ptr
->surface_desc
.u1
.lPitch
/ bpp
;
927 if (surf_ptr
->surface_desc
.u1
.lPitch
== (surf_ptr
->surface_desc
.dwWidth
* bpp
)) {
928 current_storage_width
= 0;
930 current_storage_width
= surf_ptr
->surface_desc
.u1
.lPitch
/ bpp
;
933 glPixelStorei(GL_UNPACK_ROW_LENGTH
, current_storage_width
);
935 TRACE(" initialized texture upload for level %d with conversion %d.\n", current_level
, convert_type
);
940 HRESULT
upload_surface_to_tex_memory(RECT
*rect
, DWORD xoffset
, DWORD yoffset
, void **temp_buffer
)
942 const DDSURFACEDESC
* const src_d
= (DDSURFACEDESC
*)&(current_surface
->surface_desc
);
943 void *surf_buffer
= NULL
;
946 BYTE bpp
= GET_BPP(current_surface
->surface_desc
);
952 lrect
.bottom
= current_tex_height
;
953 lrect
.right
= current_tex_width
;
957 width
= rect
->right
- rect
->left
;
958 height
= rect
->bottom
- rect
->top
;
960 if (current_surface
->surface_desc
.u4
.ddpfPixelFormat
.dwFlags
& DDPF_FOURCC
) {
962 int size
= current_surface
->surface_desc
.u1
.dwLinearSize
;
963 int width_
= current_surface
->surface_desc
.dwWidth
;
964 int height_
= current_surface
->surface_desc
.dwHeight
;
965 LPVOID buffer
= current_surface
->surface_desc
.lpSurface
;
967 switch (current_surface
->surface_desc
.u4
.ddpfPixelFormat
.dwFourCC
) {
968 case MAKE_FOURCC('D','X','T','1'): retVal
= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
; break;
969 case MAKE_FOURCC('D','X','T','3'): retVal
= GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
; break;
970 case MAKE_FOURCC('D','X','T','5'): retVal
= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
; break;
972 FIXME("Not supported\n");
977 if (GL_extensions
.s3tc_compressed_texture
) {
978 /* GL_extensions.glCompressedTexSubImage2D(GL_TEXTURE_2D, current_level, xoffset, yoffset, width, height, retVal, (unsigned char*)temp_buffer); */
979 GL_extensions
.glCompressedTexImage2D(GL_TEXTURE_2D
, current_level
, retVal
, width_
, height_
, 0, size
, buffer
);
981 ERR("Trying to upload S3TC texture whereas the device does not have support for it\n");
986 /* Used when converting stuff */
987 line_increase
= src_d
->u1
.lPitch
- (width
* bpp
);
989 switch (convert_type
) {
990 case CONVERT_PALETTED
: {
991 IDirectDrawPaletteImpl
* pal
= current_surface
->palette
;
995 BYTE
*src
= (BYTE
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
998 /* Upload a black texture. The real one will be uploaded on palette change */
999 WARN("Palettized texture Loading with a NULL palette !\n");
1000 memset(table
, 0, 256 * 4);
1002 /* Get the surface's palette */
1003 for (i
= 0; i
< 256; i
++) {
1004 table
[i
][0] = pal
->palents
[i
].peRed
;
1005 table
[i
][1] = pal
->palents
[i
].peGreen
;
1006 table
[i
][2] = pal
->palents
[i
].peBlue
;
1007 if ((src_d
->dwFlags
& DDSD_CKSRCBLT
) &&
1008 (i
>= src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) &&
1009 (i
<= src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1010 /* We should maybe here put a more 'neutral' color than the standard bright purple
1011 one often used by application to prevent the nice purple borders when bi-linear
1019 if (*temp_buffer
== NULL
)
1020 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1021 current_tex_width
* current_tex_height
* sizeof(DWORD
));
1022 dst
= (BYTE
*) *temp_buffer
;
1024 for (y
= 0; y
< height
; y
++) {
1025 for (x
= 0; x
< width
; x
++) {
1026 BYTE color
= *src
++;
1027 *dst
++ = table
[color
][0];
1028 *dst
++ = table
[color
][1];
1029 *dst
++ = table
[color
][2];
1030 *dst
++ = table
[color
][3];
1032 src
+= line_increase
;
1036 case CONVERT_CK_565
: {
1037 /* Converting the 565 format in 5551 packed to emulate color-keying.
1039 Note : in all these conversion, it would be best to average the averaging
1040 pixels to get the color of the pixel that will be color-keyed to
1041 prevent 'color bleeding'. This will be done later on if ever it is
1044 Note2: when using color-keying + alpha, are the alpha bits part of the
1045 color-space or not ?
1048 WORD
*src
= (WORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1050 if (*temp_buffer
== NULL
)
1051 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1052 current_tex_width
* current_tex_height
* sizeof(WORD
));
1053 dst
= (WORD
*) *temp_buffer
;
1055 for (y
= 0; y
< height
; y
++) {
1056 for (x
= 0; x
< width
; x
++) {
1057 WORD color
= *src
++;
1058 *dst
= ((color
& 0xFFC0) | ((color
& 0x1F) << 1));
1059 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1060 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1064 src
= (WORD
*) (((BYTE
*) src
) + line_increase
);
1068 case CONVERT_CK_5551
: {
1069 /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
1071 WORD
*src
= (WORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1073 if (*temp_buffer
== NULL
)
1074 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1075 current_tex_width
* current_tex_height
* sizeof(WORD
));
1076 dst
= (WORD
*) *temp_buffer
;
1078 for (y
= 0; y
< height
; y
++) {
1079 for (x
= 0; x
< width
; x
++) {
1080 WORD color
= *src
++;
1081 *dst
= color
& 0xFFFE;
1082 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1083 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1084 *dst
|= color
& 0x0001;
1087 src
= (WORD
*) (((BYTE
*) src
) + line_increase
);
1091 case CONVERT_CK_4444
: {
1092 /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
1094 WORD
*src
= (WORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1096 if (*temp_buffer
== NULL
)
1097 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1098 current_tex_width
* current_tex_height
* sizeof(WORD
));
1099 dst
= (WORD
*) *temp_buffer
;
1101 for (y
= 0; y
< height
; y
++) {
1102 for (x
= 0; x
< width
; x
++) {
1103 WORD color
= *src
++;
1104 *dst
= color
& 0xFFF0;
1105 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1106 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1107 *dst
|= color
& 0x000F;
1110 src
= (WORD
*) (((BYTE
*) src
) + line_increase
);
1114 case CONVERT_CK_4444_ARGB
: {
1115 /* Move the four Alpha bits... */
1117 WORD
*src
= (WORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1119 if (*temp_buffer
== NULL
)
1120 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1121 current_tex_width
* current_tex_height
* sizeof(WORD
));
1122 dst
= (WORD
*) *temp_buffer
;
1124 for (y
= 0; y
< height
; y
++) {
1125 for (x
= 0; x
< width
; x
++) {
1126 WORD color
= *src
++;
1127 *dst
= (color
& 0x0FFF) << 4;
1128 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1129 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1130 *dst
|= (color
& 0xF000) >> 12;
1133 src
= (WORD
*) (((BYTE
*) src
) + line_increase
);
1137 case CONVERT_CK_1555
: {
1139 WORD
*src
= (WORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1141 if (*temp_buffer
== NULL
)
1142 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1143 current_tex_width
* current_tex_height
* sizeof(WORD
));
1144 dst
= (WORD
*) *temp_buffer
;
1146 for (y
= 0; y
< height
; y
++) {
1147 for (x
= 0; x
< width
; x
++) {
1148 WORD color
= *src
++;
1149 *dst
= (color
& 0x7FFF) << 1;
1150 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1151 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1152 *dst
|= (color
& 0x8000) >> 15;
1155 src
= (WORD
*) (((BYTE
*) src
) + line_increase
);
1160 /* Converting the 0555 format in 5551 packed */
1162 WORD
*src
= (WORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1164 if (*temp_buffer
== NULL
)
1165 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1166 current_tex_width
* current_tex_height
* sizeof(WORD
));
1167 dst
= (WORD
*) *temp_buffer
;
1169 if (src_d
->dwFlags
& DDSD_CKSRCBLT
) {
1170 for (y
= 0; y
< height
; y
++) {
1171 for (x
= 0; x
< width
; x
++) {
1172 WORD color
= *src
++;
1173 *dst
= (color
& 0x7FFF) << 1;
1174 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1175 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1179 src
= (WORD
*) (((BYTE
*) src
) + line_increase
);
1182 for (y
= 0; y
< height
; y
++) {
1183 for (x
= 0; x
< width
; x
++) {
1184 WORD color
= *src
++;
1185 *dst
++ = ((color
& 0x7FFF) << 1) | 0x0001;
1187 src
= (WORD
*) (((BYTE
*) src
) + line_increase
);
1193 case CONVERT_CK_RGB24
: {
1194 /* This is a pain :-) */
1196 BYTE
*src
= (BYTE
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
));
1199 if (*temp_buffer
== NULL
)
1200 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1201 current_tex_width
* current_tex_height
* sizeof(DWORD
));
1202 dst
= (DWORD
*) *temp_buffer
;
1204 for (y
= 0; y
< height
; y
++) {
1205 for (x
= 0; x
< width
; x
++) {
1206 DWORD color
= *((DWORD
*) src
) & 0x00FFFFFF;
1209 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1210 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1214 src
+= line_increase
;
1218 case CONVERT_CK_8888
: {
1219 /* Just use the alpha component to handle color-keying... */
1221 DWORD
*src
= (DWORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1223 if (*temp_buffer
== NULL
)
1224 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1225 current_tex_width
* current_tex_height
* sizeof(DWORD
));
1226 dst
= (DWORD
*) *temp_buffer
;
1228 for (y
= 0; y
< height
; y
++) {
1229 for (x
= 0; x
< width
; x
++) {
1230 DWORD color
= *src
++;
1231 *dst
= color
& 0xFFFFFF00;
1232 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1233 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1234 *dst
|= color
& 0x000000FF;
1237 src
= (DWORD
*) (((BYTE
*) src
) + line_increase
);
1241 case CONVERT_CK_8888_ARGB
: {
1243 DWORD
*src
= (DWORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1245 if (*temp_buffer
== NULL
)
1246 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1247 current_tex_width
* current_tex_height
* sizeof(DWORD
));
1248 dst
= (DWORD
*) *temp_buffer
;
1250 for (y
= 0; y
< height
; y
++) {
1251 for (x
= 0; x
< width
; x
++) {
1252 DWORD color
= *src
++;
1253 *dst
= (color
& 0x00FFFFFF) << 8;
1254 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1255 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1256 *dst
|= (color
& 0xFF000000) >> 24;
1259 src
= (DWORD
*) (((BYTE
*) src
) + line_increase
);
1263 case CONVERT_RGB32_888
: {
1264 /* Just add an alpha component and handle color-keying... */
1266 DWORD
*src
= (DWORD
*) (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
)), *dst
;
1268 if (*temp_buffer
== NULL
)
1269 *temp_buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1270 current_tex_width
* current_tex_height
* sizeof(DWORD
));
1271 dst
= (DWORD
*) *temp_buffer
;
1273 if (src_d
->dwFlags
& DDSD_CKSRCBLT
) {
1274 for (y
= 0; y
< height
; y
++) {
1275 for (x
= 0; x
< width
; x
++) {
1276 DWORD color
= *src
++;
1278 if ((color
< src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
1279 (color
> src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
1283 src
= (DWORD
*) (((BYTE
*) src
) + line_increase
);
1286 for (y
= 0; y
< height
; y
++) {
1287 for (x
= 0; x
< width
; x
++) {
1288 *dst
++ = (*src
++ << 8) | 0xFF;
1290 src
= (DWORD
*) (((BYTE
*) src
) + line_increase
);
1296 /* Nothing to do here as the name suggests... Just set-up the buffer correctly */
1297 surf_buffer
= (((BYTE
*) src_d
->lpSurface
) + (bpp
* rect
->left
) + (src_d
->u1
.lPitch
* rect
->top
));
1301 if (convert_type
!= NO_CONVERSION
) {
1302 /* When doing conversion, the storage is always of width 'width' as there will never
1303 be any Pitch issue... For now :-)
1305 surf_buffer
= *temp_buffer
;
1306 if (width
!= current_storage_width
) {
1307 glPixelStorei(GL_UNPACK_ROW_LENGTH
, width
);
1308 current_storage_width
= width
;
1312 glTexSubImage2D(GL_TEXTURE_2D
,
1317 current_pixel_format
,
1323 HRESULT
upload_surface_to_tex_memory_release(void)
1325 current_surface
= NULL
;