- implement the texturing the D3D3 way

- prepare for multi-texturing support
This commit is contained in:
Lionel Ulmer 2002-12-02 18:59:11 +00:00 committed by Alexandre Julliard
parent 0e32a2bf85
commit 41fcb0bbe4
4 changed files with 149 additions and 17 deletions

View File

@ -167,6 +167,9 @@ struct IDirect3DExecuteBufferImpl
/*****************************************************************************
* IDirect3DDevice implementation structure
*/
#define MAX_TEXTURES 8
struct IDirect3DDeviceImpl
{
ICOM_VFIELD_MULTI(IDirect3DDevice7);
@ -180,7 +183,7 @@ struct IDirect3DDeviceImpl
IDirect3DViewportImpl *viewport_list;
IDirect3DViewportImpl *current_viewport;
IDirect3DTextureImpl *current_texture;
IDirect3DTextureImpl *current_texture[MAX_TEXTURES];
void (*set_context)(IDirect3DDeviceImpl*);
};

View File

@ -92,9 +92,12 @@ Main_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
if (!--(This->ref)) {
/* Release texture associated with the device */
if (This->current_texture != NULL)
IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture, IDirect3DTexture2));
int i;
/* Release texture associated with the device */
for (i = 0; i < MAX_TEXTURES; i++) {
if (This->current_texture[i] != NULL)
IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[i], IDirect3DTexture2));
}
HeapFree(GetProcessHeap(), 0, This);
return 0;

View File

@ -317,8 +317,8 @@ GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
if (!--(This->ref)) {
/* Release texture associated with the device */
if (This->current_texture != NULL)
IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture, IDirect3DTexture2));
if (This->current_texture[0] != NULL)
IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[0], IDirect3DTexture2));
ENTER_GL();
glXDestroyContext(glThis->display, glThis->gl_context);
@ -1059,6 +1059,135 @@ GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
return DD_OK;
}
HRESULT WINAPI
GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
DWORD dwStage,
D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
DWORD dwState)
{
ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
GLenum gl_state;
TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
if (TRACE_ON(ddraw)) {
TRACE(" Stage type is : ");
switch (d3dTexStageStateType) {
#define GEN_CASE(a) case a: DPRINTF(#a " "); break
GEN_CASE(D3DTSS_COLOROP);
GEN_CASE(D3DTSS_COLORARG1);
GEN_CASE(D3DTSS_COLORARG2);
GEN_CASE(D3DTSS_ALPHAOP);
GEN_CASE(D3DTSS_ALPHAARG1);
GEN_CASE(D3DTSS_ALPHAARG2);
GEN_CASE(D3DTSS_BUMPENVMAT00);
GEN_CASE(D3DTSS_BUMPENVMAT01);
GEN_CASE(D3DTSS_BUMPENVMAT10);
GEN_CASE(D3DTSS_BUMPENVMAT11);
GEN_CASE(D3DTSS_TEXCOORDINDEX);
GEN_CASE(D3DTSS_ADDRESS);
GEN_CASE(D3DTSS_ADDRESSU);
GEN_CASE(D3DTSS_ADDRESSV);
GEN_CASE(D3DTSS_BORDERCOLOR);
GEN_CASE(D3DTSS_MAGFILTER);
GEN_CASE(D3DTSS_MINFILTER);
GEN_CASE(D3DTSS_MIPFILTER);
GEN_CASE(D3DTSS_MIPMAPLODBIAS);
GEN_CASE(D3DTSS_MAXMIPLEVEL);
GEN_CASE(D3DTSS_MAXANISOTROPY);
GEN_CASE(D3DTSS_BUMPENVLSCALE);
GEN_CASE(D3DTSS_BUMPENVLOFFSET);
GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
#undef GEN_CASE
default: DPRINTF("UNKNOWN !!!");
}
DPRINTF(" => ");
}
switch (d3dTexStageStateType) {
case D3DTSS_MINFILTER:
switch ((D3DTEXTUREMINFILTER) dwState) {
case D3DTFN_POINT:
if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_POINT\n");
gl_state = GL_NEAREST;
break;
case D3DTFN_LINEAR:
if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_LINEAR\n");
gl_state = GL_LINEAR;
break;
default:
if (TRACE_ON(ddraw)) DPRINTF(" state unhandled.\n");
gl_state = GL_LINEAR;
break;
}
glThis->render_state.min = gl_state;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_state);
break;
case D3DTSS_MAGFILTER:
switch ((D3DTEXTUREMAGFILTER) dwState) {
case D3DTFG_POINT:
if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_POINT\n");
gl_state = GL_NEAREST;
break;
case D3DTFG_LINEAR:
if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_LINEAR\n");
gl_state = GL_LINEAR;
break;
default:
if (TRACE_ON(ddraw)) DPRINTF(" state unhandled.\n");
gl_state = GL_LINEAR;
break;
}
glThis->render_state.mag = gl_state;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_state);
break;
default:
if (TRACE_ON(ddraw)) DPRINTF(" unhandled.\n");
}
return DD_OK;
}
HRESULT WINAPI
GL_IDirect3DDeviceImpl_3_SetTexture(LPDIRECT3DDEVICE3 iface,
DWORD dwStage,
LPDIRECT3DTEXTURE2 lpTexture2)
{
ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2);
if (This->current_texture[dwStage] != NULL) {
/* Seems that this is not right... Need to test in real Windows
IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirect3DTexture2)); */
}
ENTER_GL();
if (lpTexture2 == NULL) {
TRACE(" disabling 2D texturing.\n");
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
} else {
IDirect3DTextureImpl *tex_impl = ICOM_OBJECT(IDirect3DTextureImpl, IDirect3DTexture2, lpTexture2);
IDirect3DTextureGLImpl *tex_glimpl = (IDirect3DTextureGLImpl *) tex_impl;
This->current_texture[dwStage] = tex_impl;
IDirect3DTexture2_AddRef(lpTexture2);
TRACE(" activating OpenGL texture %d.\n", tex_glimpl->tex_name);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex_glimpl->tex_name);
}
LEAVE_GL();
return DD_OK;
}
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
#else
@ -1105,7 +1234,7 @@ ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_GetTexture,
XCAST(SetTexture) Main_IDirect3DDeviceImpl_7_SetTexture,
XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
XCAST(SetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
XCAST(SetTextureStageState) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
@ -1171,7 +1300,7 @@ ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
XCAST(DrawIndexedPrimitiveVB) Main_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
XCAST(GetTexture) Main_IDirect3DDeviceImpl_3_GetTexture,
XCAST(SetTexture) Main_IDirect3DDeviceImpl_3_SetTexture,
XCAST(SetTexture) GL_IDirect3DDeviceImpl_3_SetTexture,
XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
@ -1382,9 +1511,6 @@ d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfa
object->ref = 1;
object->d3d = d3d;
object->surface = surface;
object->viewport_list = NULL;
object->current_viewport = NULL;
object->current_texture = NULL;
object->set_context = set_context;
TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);

View File

@ -249,7 +249,7 @@ ULONG WINAPI
Main_IDirect3DTextureImpl_2_1T_AddRef(LPDIRECT3DTEXTURE2 iface)
{
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
FIXME("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
return ++(This->ref);
}
@ -337,8 +337,8 @@ GL_IDirect3DTextureImpl_2_1T_Release(LPDIRECT3DTEXTURE2 iface)
/* And if this texture was the current one, remove it at the device level */
if (This->d3ddevice != NULL)
if (This->d3ddevice->current_texture == This)
This->d3ddevice->current_texture = NULL;
if (This->d3ddevice->current_texture[0] == This)
This->d3ddevice->current_texture[0] = NULL;
if (This->loaded) {
mem_used = This->surface->surface_desc.dwHeight *
@ -378,10 +378,10 @@ GL_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface,
/* Associate the texture with the device and perform the appropriate AddRef/Release */
/* FIXME: Is there only one or several textures associated with the device ? */
if (lpDeviceImpl->current_texture != NULL)
IDirect3DTexture2_Release(ICOM_INTERFACE(lpDeviceImpl->current_texture, IDirect3DTexture2));
if (lpDeviceImpl->current_texture[0] != NULL)
IDirect3DTexture2_Release(ICOM_INTERFACE(lpDeviceImpl->current_texture[0], IDirect3DTexture2));
IDirect3DTexture2_AddRef(ICOM_INTERFACE(This, IDirect3DTexture2));
lpDeviceImpl->current_texture = This;
lpDeviceImpl->current_texture[0] = This;
TRACE("OpenGL texture handle is : %d\n", glThis->tex_name);