Changelog: - revert some optimisations breaking some games - added a new texture format (4444 ARGB) - fixed the computation of colors - added new render states and fog support (NOT handled yet for transformed vertices) -- Lionel Ulmer - http://www.bbrox.org/
--- ../wine_base/dlls/ddraw/d3dtexture.c Sun Dec 15 18:47:58 2002 +++ dlls/ddraw/d3dtexture.c Sun Dec 15 20:22:27 2002 @@ -397,6 +397,37 @@ GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, src_d->lpSurface); + } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000F000) { + /* Move the four Alpha bits... */ + WORD *surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); + DWORD i; + WORD *src = (WORD *) src_d->lpSurface, *dst = surface; + + for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) { + *dst++ = (((*src & 0xFFF0) >> 4) | + ((*src & 0x000F) << 12)); + src++; + } + + if (init_upload) + glTexImage2D(GL_TEXTURE_2D, + glThis->mipmap_level, + GL_RGBA, + src_d->dwWidth, src_d->dwHeight, + 0, + GL_RGBA, + GL_UNSIGNED_SHORT_4_4_4_4, + surface); + else + glTexSubImage2D(GL_TEXTURE_2D, + glThis->mipmap_level, + 0, 0, + src_d->dwWidth, src_d->dwHeight, + GL_RGBA, + GL_UNSIGNED_SHORT_4_4_4_4, + surface); + + HeapFree(GetProcessHeap(), 0, surface); } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00008000) { /* Converting the 1555 format in 5551 packed */ WORD *surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); @@ -779,17 +810,6 @@ XCAST(Load) GL_IDirect3DTextureImpl_2_1T_Load, }; -ICOM_VTABLE(IDirect3DTexture2) STUB_VTABLE_IDirect3DTexture2 = -{ - ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE - XCAST(QueryInterface) Thunk_IDirect3DTextureImpl_2_QueryInterface, - XCAST(AddRef) Thunk_IDirect3DTextureImpl_2_AddRef, - XCAST(Release) Thunk_IDirect3DTextureImpl_2_Release, - XCAST(GetHandle) Main_IDirect3DTextureImpl_2_1T_GetHandle, - XCAST(PaletteChanged) Main_IDirect3DTextureImpl_2_1T_PaletteChanged, - XCAST(Load) Main_IDirect3DTextureImpl_2_1T_Load, -}; - #if !defined(__STRICT_ANSI__) && defined(__GNUC__) #undef XCAST #endif @@ -823,14 +843,6 @@ { IDirect3DTextureGLImpl *private; - if ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY)) != 0) { - /* If it is an offscreen texture, only create stub implementations. - Only the IUnknown interfaces should be used anyway. */ - ICOM_INIT_INTERFACE(surf, IDirect3DTexture, VTABLE_IDirect3DTexture); /* No special STUB one here as all functions are stubs */ - ICOM_INIT_INTERFACE(surf, IDirect3DTexture2, STUB_VTABLE_IDirect3DTexture2); - return DD_OK; - } - private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTextureGLImpl)); if (private == NULL) return DDERR_OUTOFMEMORY; --- ../wine_base/dlls/ddraw/mesa.c Sun Dec 15 18:47:58 2002 +++ dlls/ddraw/mesa.c Sun Dec 15 21:45:38 2002 @@ -83,6 +83,7 @@ } } break; + case D3DRENDERSTATE_TEXTUREADDRESSU: /* 44 */ case D3DRENDERSTATE_TEXTUREADDRESSV: /* 45 */ case D3DRENDERSTATE_TEXTUREADDRESS: { /* 3 */ @@ -268,7 +269,34 @@ else glDisable(GL_BLEND); break; + + case D3DRENDERSTATE_FOGENABLE: /* 28 */ + if (dwRenderState) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + break; + + case D3DRENDERSTATE_SPECULARENABLE: /* 29 */ + if (dwRenderState) + ERR(" Specular Lighting not supported yet.\n"); + break; + + case D3DRENDERSTATE_SUBPIXEL: /* 31 */ + case D3DRENDERSTATE_SUBPIXELX: /* 32 */ + /* We do not support this anyway, so why protest :-) */ + break; + + case D3DRENDERSTATE_FOGCOLOR: { /* 34 */ + GLint color[4]; + color[0] = (dwRenderState >> 16) & 0xFF; + color[1] = (dwRenderState >> 8) & 0xFF; + color[2] = (dwRenderState >> 0) & 0xFF; + color[3] = (dwRenderState >> 24) & 0xFF; + glFogiv(GL_FOG_COLOR, color); + } break; + case D3DRENDERSTATE_COLORKEYENABLE: /* 41 */ if (dwRenderState) glEnable(GL_BLEND); @@ -276,6 +304,20 @@ glDisable(GL_BLEND); break; + case D3DRENDERSTATE_ZBIAS: /* 47 */ + /* This is a tad bit hacky.. But well, no idea how to do it better in OpenGL :-/ */ + if (dwRenderState == 0) { + glDisable(GL_POLYGON_OFFSET_FILL); + glDisable(GL_POLYGON_OFFSET_LINE); + glDisable(GL_POLYGON_OFFSET_POINT); + } else { + glEnable(GL_POLYGON_OFFSET_FILL); + glEnable(GL_POLYGON_OFFSET_LINE); + glEnable(GL_POLYGON_OFFSET_POINT); + glPolygonOffset(1.0, dwRenderState * 1.0); + } + break; + case D3DRENDERSTATE_FLUSHBATCH: /* 50 */ break; --- ../wine_base/dlls/ddraw/d3ddevice/mesa.c Sun Dec 15 19:25:19 2002 +++ dlls/ddraw/d3ddevice/mesa.c Sun Dec 15 21:45:07 2002 @@ -733,23 +733,24 @@ D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]); DWORD col = vx->u4.color; - glColor3f(((col >> 16) & 0xFF) / 255.0, - ((col >> 8) & 0xFF) / 255.0, - ((col >> 0) & 0xFF) / 255.0); + glColor4ub((col >> 16) & 0xFF, + (col >> 8) & 0xFF, + (col >> 0) & 0xFF, + (col >> 24) & 0xFF); glVertex3f(vx->u1.x, vx->u2.y, vx->u3.z); - TRACE(" LV: %f %f %f (%02lx %02lx %02lx)\n", + TRACE(" LV: %f %f %f (%02lx %02lx %02lx %02lx)\n", vx->u1.x, vx->u2.y, vx->u3.z, - ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF)); + ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF), ((col >> 24) & 0xFF)); } break; case D3DVT_TLVERTEX: { D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]); DWORD col = vx->u5.color; - glColor4ub((col >> 24) & 0xFF, - (col >> 16) & 0xFF, + glColor4ub((col >> 16) & 0xFF, (col >> 8) & 0xFF, - (col >> 0) & 0xFF); + (col >> 0) & 0xFF, + (col >> 24) & 0xFF); glTexCoord2f(vx->u7.tu, vx->u8.tv); if (vx->u4.rhw < 0.01) glVertex3f(vx->u1.sx, @@ -760,9 +761,9 @@ vx->u2.sy / vx->u4.rhw, vx->u3.sz / vx->u4.rhw, 1.0 / vx->u4.rhw); - TRACE(" TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n", + TRACE(" TLV: %f %f %f (%02lx %02lx %02lx %02lx) (%f %f) (%f)\n", vx->u1.sx, vx->u2.sy, vx->u3.sz, - ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF), + ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF), ((col >> 24) & 0xFF), vx->u7.tu, vx->u8.tv, vx->u4.rhw); } break; @@ -926,10 +927,10 @@ } static void handle_diffuse(char *vertex, int offset, int extra) { DWORD color = *((DWORD *) (vertex + offset)); - glColor4ub((color >> 24) & 0xFF, - (color >> 16) & 0xFF, + glColor4ub((color >> 16) & 0xFF, (color >> 8) & 0xFF, - (color >> 0) & 0xFF); + (color >> 0) & 0xFF, + (color >> 24) & 0xFF); } static void handle_texture(char *vertex, int offset, int extra) { if (extra == 0xFF) { @@ -983,10 +984,10 @@ for (index = 0; index < dwIndexCount; index++) { int i = (dwIndices == NULL) ? index : dwIndices[index]; - glColor4ub((vertices[i].diffuse >> 24) & 0xFF, - (vertices[i].diffuse >> 16) & 0xFF, + glColor4ub((vertices[i].diffuse >> 16) & 0xFF, (vertices[i].diffuse >> 8) & 0xFF, - (vertices[i].diffuse >> 0) & 0xFF); + (vertices[i].diffuse >> 0) & 0xFF, + (vertices[i].diffuse >> 24) & 0xFF); /* Todo : handle specular... */ glTexCoord2fv(&(vertices[i].tu1)); if (vertices[i].rhw < 0.00001) @@ -998,14 +999,14 @@ 1.0 / vertices[i].rhw); TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n", vertices[i].x, vertices[i].y, vertices[i].z, vertices[i].rhw, - (vertices[i].diffuse >> 24) & 0xFF, (vertices[i].diffuse >> 16) & 0xFF, (vertices[i].diffuse >> 8) & 0xFF, (vertices[i].diffuse >> 0) & 0xFF, - (vertices[i].specular >> 24) & 0xFF, + (vertices[i].diffuse >> 24) & 0xFF, (vertices[i].specular >> 16) & 0xFF, (vertices[i].specular >> 8) & 0xFF, (vertices[i].specular >> 0) & 0xFF, + (vertices[i].specular >> 24) & 0xFF, vertices[i].tu1, vertices[i].tv1); } } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) || @@ -1144,23 +1145,23 @@ for (index = 0; index < dwIndexCount; index++) { int i = (dwIndices == NULL) ? index : dwIndices[index]; - glColor4ub((CPNT(diffuse,i,0,DWORD) >> 24) & 0xFF, - (CPNT(diffuse,i,0,DWORD) >> 16) & 0xFF, + glColor4ub((CPNT(diffuse,i,0,DWORD) >> 16) & 0xFF, (CPNT(diffuse,i,0,DWORD) >> 8) & 0xFF, - (CPNT(diffuse,i,0,DWORD) >> 0) & 0xFF); + (CPNT(diffuse,i,0,DWORD) >> 0) & 0xFF, + (CPNT(diffuse,i,0,DWORD) >> 24) & 0xFF); /* Todo : handle specular... */ glTexCoord2f(CPNT(textureCoords[1],i,0,D3DVALUE),CPNT(textureCoords[1],i,1,D3DVALUE)); glVertex3f(CPNT(position,i,0,D3DVALUE),CPNT(position,i,1,D3DVALUE),CPNT(position,i,2,D3DVALUE)); TRACE(" %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n", CPNT(position,i,0,D3DVALUE),CPNT(position,i,1,D3DVALUE),CPNT(position,i,2,D3DVALUE), - (CPNT(diffuse,i,0,DWORD) >> 24) & 0xFF, (CPNT(diffuse,i,0,DWORD) >> 16) & 0xFF, (CPNT(diffuse,i,0,DWORD) >> 8) & 0xFF, (CPNT(diffuse,i,0,DWORD) >> 0) & 0xFF, - (CPNT(specular,i,0,DWORD) >> 24) & 0xFF, + (CPNT(diffuse,i,0,DWORD) >> 24) & 0xFF, (CPNT(specular,i,0,DWORD) >> 16) & 0xFF, (CPNT(specular,i,0,DWORD) >> 8) & 0xFF, (CPNT(specular,i,0,DWORD) >> 0) & 0xFF, + (CPNT(specular,i,0,DWORD) >> 24) & 0xFF, CPNT(textureCoords[0],i,0,D3DVALUE),CPNT(textureCoords[0],i,1,D3DVALUE)); } } --- ../wine_base/dlls/ddraw/ddraw/main.c Sun Dec 15 12:15:49 2002 +++ dlls/ddraw/ddraw/main.c Sun Dec 15 20:10:22 2002 @@ -557,6 +557,11 @@ /* create backbuffer surface */ hr = This->create_backbuffer(This, pDDSD, ppSurf, pUnkOuter, NULL); } + else if (pDDSD->ddsCaps.dwCaps & DDSCAPS_TEXTURE) + { + /* create texture */ + hr = create_texture(This, pDDSD, ppSurf, pUnkOuter); + } else if ((pDDSD->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) || (pDDSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)) /* No difference in Wine right now */ { @@ -567,11 +572,6 @@ { /* create z-buffer */ hr = This->create_zbuffer(This, pDDSD, ppSurf, pUnkOuter); - } - else if (pDDSD->ddsCaps.dwCaps & DDSCAPS_TEXTURE) - { - /* create texture */ - hr = create_texture(This, pDDSD, ppSurf, pUnkOuter); } else {