D3D 65 Changelog: Added support for per-vertex material properties Note: this will be relatively slow, but well, at least it should be pretty complete :-) Note2: with these latest patches, the first game that is using untransformed vertices seems to work pretty well (Messiah). Did not compare visually to what it does in Windows though. Updated the d3d_status.html page with a screenshot. -- Lionel Ulmer - http://www.bbrox.org/
--- /home/ulmer/Wine/wine_base//dlls/ddraw/d3ddevice/mesa.c 2002-12-29 15:16:14.000000000 +0100 +++ /home/ulmer/Wine/wine_work//dlls/ddraw/d3ddevice/mesa.c 2002-12-29 15:41:26.000000000 +0100 @@ -941,26 +941,92 @@ inline static void handle_normal(D3DVALUE *coords) { glNormal3fv(coords); } -inline static void handle_specular(DWORD *color) { - /* Specular not handled yet properly... */ + +inline static void handle_diffuse_base(RenderState *rs, DWORD *color) { + if (rs->alpha_blend_enable == TRUE) { + glColor4ub((*color >> 16) & 0xFF, + (*color >> 8) & 0xFF, + (*color >> 0) & 0xFF, + (*color >> 24) & 0xFF); + } else { + glColor3ub((*color >> 16) & 0xFF, + (*color >> 8) & 0xFF, + (*color >> 0) & 0xFF); + } } -inline static void handle_diffuse(DWORD *color) { + +inline static void handle_specular_base(RenderState *rs, DWORD *color) { glColor4ub((*color >> 16) & 0xFF, (*color >> 8) & 0xFF, (*color >> 0) & 0xFF, - (*color >> 24) & 0xFF); + (*color >> 24) & 0xFF); /* No idea if the alpha field is really used.. */ } -inline static void handle_diffuse_and_specular(DWORD *color_d, DWORD *color_s) { - handle_diffuse(color_d); + +inline static void handle_diffuse(RenderState *rs, DWORD *color) { + if (rs->lighting_enable == TRUE) { + if (rs->color_diffuse == D3DMCS_COLOR1) { + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + handle_diffuse_base(rs, color); + } + if (rs->color_ambient == D3DMCS_COLOR1) { + glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT); + handle_diffuse_base(rs, color); + } + if ((rs->color_specular == D3DMCS_COLOR1) && (rs->specular_enable == TRUE)) { + glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); + handle_diffuse_base(rs, color); + } + if (rs->color_emissive == D3DMCS_COLOR1) { + glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION); + handle_diffuse_base(rs, color); + } + } else { + handle_diffuse_base(rs, color); + } } -inline static void handle_diffuse_no_alpha(DWORD *color) { - glColor3ub((*color >> 16) & 0xFF, - (*color >> 8) & 0xFF, - (*color >> 0) & 0xFF); + +inline static void handle_specular(RenderState *rs, DWORD *color) { + if (rs->lighting_enable == TRUE) { + if (rs->color_diffuse == D3DMCS_COLOR2) { + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + handle_specular(rs, color); + } + if (rs->color_ambient == D3DMCS_COLOR2) { + glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT); + handle_specular(rs, color); + } + if ((rs->color_specular == D3DMCS_COLOR2) && (rs->specular_enable == TRUE)) { + glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); + handle_specular(rs, color); + } + if (rs->color_emissive == D3DMCS_COLOR2) { + glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION); + handle_specular(rs, color); + } + } + /* No else here as we do not know how to handle 'specular' on its own in any case.. */ } -inline static void handle_diffuse_and_specular_no_alpha(DWORD *color_d, DWORD *color_s) { - handle_diffuse_no_alpha(color_d); + +inline static void handle_diffuse_and_specular(RenderState *rs, DWORD *color_d, DWORD *color_s, BOOLEAN transformed) { + if (transformed == TRUE) { + if (rs->fog_on == TRUE) { + /* Special case where the specular value is used to do fogging. TODO */ + } + if (rs->specular_enable == TRUE) { + /* Standard specular value in transformed mode. TODO */ + } + handle_diffuse_base(rs, color_d); + } else { + if (rs->lighting_enable == TRUE) { + handle_diffuse(rs, color_d); + handle_specular(rs, color_s); + } else { + /* In that case, only put the diffuse color... */ + handle_diffuse_base(rs, color_d); + } + } } + inline static void handle_texture(D3DVALUE *coords) { glTexCoord2fv(coords); } @@ -1026,10 +1092,7 @@ D3DVALUE *position = (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride); - if (glThis->render_state.alpha_blend_enable == TRUE) - handle_diffuse_and_specular(color_d, color_s); - else - handle_diffuse_and_specular_no_alpha(color_d, color_s); + handle_diffuse_and_specular(&(glThis->render_state), color_d, color_s, TRUE); handle_texture(tex_coord); handle_xyzrhw(position); @@ -1064,22 +1127,16 @@ (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride); DWORD *color_s = (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride); - if (glThis->render_state.alpha_blend_enable == TRUE) - handle_diffuse_and_specular(color_d, color_s); - else - handle_diffuse_and_specular_no_alpha(color_d, color_s); + handle_diffuse_and_specular(&(glThis->render_state), color_d, color_s, (d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW); } else { if (d3dvtVertexType & D3DFVF_SPECULAR) { DWORD *color_s = (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride); - handle_specular(color_s); + handle_specular(&(glThis->render_state), color_s); } else if (d3dvtVertexType & D3DFVF_DIFFUSE) { DWORD *color_d = (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride); - if (glThis->render_state.alpha_blend_enable == TRUE) - handle_diffuse(color_d); - else - handle_diffuse_no_alpha(color_d); + handle_diffuse(&(glThis->render_state), color_d); } }