dnl/*========================================================================== dnl * dnl * Copyright (C) 1998 Microsoft Corporation. All Rights Reserved. dnl * dnl * File: pvvid.h dnl * Content: Common defines for the geometry inner loop dnl * dnl ***************************************************************************/ #define NEXT(pointer, stride, type) pointer = (type*)((char*)pointer + stride); dnl dnl//-------------------------------------------------------------------------- dnl d_forloop dnl FOR loop dnl dnl Arguments: dnl $1 - loop variable dnl $2 - start value dnl $3 - end value dnl $4 - loop body dnl define(`d_forloop', `pushdef(`$1', `$2')d_forloopi(`$1', `$2', `$3', `$4')popdef(`$1')')dnl define(`d_forloopi', `$4`'ifelse($1, `$3', , `define(`$1', incr($1))d_forloopi(`$1', `$2', `$3', `$4')')')dnl dnl//-------------------------------------------------------------------------- dnl d_margin dnl dnl Repeats spaces ($1)*4 times dnl Arguments: dnl $1 - margin dnl define(`d_margin',`d_forloop(`i',1,eval(($1)*4),` ')')dnl dnl dnl//-------------------------------------------------------------------------- define(`d_empty_',`')dnl dnl//-------------------------------------------------------------------------- dnl// d_TransformVertex dnl// dnl// $1 - margin count dnl// $2 - input vector (D3DVECTOR*) dnl// $3 - matrix (D3DMATRIX*) dnl// $4 - output x dnl// $5 - output y dnl// $6 - output z dnl// $7 - output w dnl// $8 - pointer to weights dnl// $9 - pointer to matrix indices (BYTE*) dnl// define(`d_TransformVertex',`dnl d_empty_($1)if (pv->dwNumVerBlends == 0) d_margin($1){ d_margin($1) $4 = $2->x*$3->_11 + $2->y*$3->_21 + $2->z*$3->_31 + $3->_41; d_margin($1) $5 = $2->x*$3->_12 + $2->y*$3->_22 + $2->z*$3->_32 + $3->_42; d_margin($1) $6 = $2->x*$3->_13 + $2->y*$3->_23 + $2->z*$3->_33 + $3->_43; d_margin($1) $7 = $2->x*$3->_14 + $2->y*$3->_24 + $2->z*$3->_34 + $3->_44; d_margin($1)} d_margin($1)else d_margin($1){ d_margin($1) D3DVALUE* pWeight = (D3DVALUE*)($8); d_margin($1) D3DVALUE weight = 0; // Sum of all vertex weights d_margin($1) D3DVALUE xx, yy, zz, ww; d_margin($1) xx = 0; d_margin($1) yy = 0; d_margin($1) zz = 0; d_margin($1) ww = 0; d_margin($1) for (DWORD i=0; i <= pv->dwNumWeights; i++) d_margin($1) { d_margin($1) D3DVALUE t; d_margin($1) if (i == pv->dwNumWeights) d_margin($1) t = 1.0f - weight; d_margin($1) else d_margin($1) { d_margin($1) t = pWeight[i]; d_margin($1) weight += t; d_margin($1) } d_margin($1) D3DMATRIXI *m = pv->GetMatrixCTM(($9)[i]); d_margin($1) xx += ($2->x*m->_11 + $2->y*m->_21 + $2->z*m->_31 + m->_41) * t; d_margin($1) yy += ($2->x*m->_12 + $2->y*m->_22 + $2->z*m->_32 + m->_42) * t; d_margin($1) zz += ($2->x*m->_13 + $2->y*m->_23 + $2->z*m->_33 + m->_43) * t; d_margin($1) ww += ($2->x*m->_14 + $2->y*m->_24 + $2->z*m->_34 + m->_44) * t; d_margin($1) } d_margin($1) $4 = xx; d_margin($1) $5 = yy; d_margin($1) $6 = zz; d_margin($1) $7 = ww; d_margin($1)}') dnl dnl//-------------------------------------------------------------------------- dnl// d_TransformVertexToCameraSpace dnl// dnl// This part of code transforms vertex and normal to the camera space to do dnl// lighting there dnl// dnl// Input: dnl// $1 - margin count dnl// $2 - pointer to the vertex coordinates (D3DVERTEX*) dnl// $3 - pointer to the output vertex (D3DVERTEX*) dnl// $4 - pointer to the input weights dnl// $5 - pointer to the input matrix indices (BYTE*) dnl// define(`d_TransformVertexToCameraSpace',`dnl d_empty_($1)if (pv->dwNumVerBlends == 0) d_margin($1){ d_margin($1) $3->x = $2->x*pv->mWV[0]._11 + d_margin($1) $2->y*pv->mWV[0]._21 + d_margin($1) $2->z*pv->mWV[0]._31 + pv->mWV[0]._41; d_margin($1) $3->y = $2->x*pv->mWV[0]._12 + d_margin($1) $2->y*pv->mWV[0]._22 + d_margin($1) $2->z*pv->mWV[0]._32 + pv->mWV[0]._42; d_margin($1) $3->z = $2->x*pv->mWV[0]._13 + d_margin($1) $2->y*pv->mWV[0]._23 + d_margin($1) $2->z*pv->mWV[0]._33 + pv->mWV[0]._43; d_margin($1)} d_margin($1)else d_margin($1){ d_margin($1) D3DVALUE* pWeight = (D3DVALUE*)($4); d_margin($1) D3DVALUE weight = 0; d_margin($1) $3->x = 0; d_margin($1) $3->y = 0; d_margin($1) $3->z = 0; d_margin($1) for (DWORD i=0; i <= pv->dwNumWeights; i++) d_margin($1) { d_margin($1) D3DVALUE t; d_margin($1) if (i == pv->dwNumWeights) d_margin($1) t = 1.0f - weight; d_margin($1) else d_margin($1) { d_margin($1) t = pWeight[i]; d_margin($1) weight += t; d_margin($1) } d_margin($1) D3DMATRIXI *m = pv->GetMatrixWV(($5)[i]); d_margin($1) $3->x += ($2->x*m->_11 + $2->y*m->_21 + $2->z*m->_31 + m->_41) * t; d_margin($1) $3->y += ($2->x*m->_12 + $2->y*m->_22 + $2->z*m->_32 + m->_42) * t; d_margin($1) $3->z += ($2->x*m->_13 + $2->y*m->_23 + $2->z*m->_33 + m->_43) * t; d_margin($1) } d_margin($1)}') dnl dnl//-------------------------------------------------------------------------- dnl// d_TransformNormalToCameraSpace dnl// dnl// This part of code transforms vertex and normal to the camera space to do dnl// lighting there dnl// dnl// Input: dnl// $1 - margin count dnl// $2 - pointer to the normal (D3DVECTOR*) dnl// $3 - pointer to the output normal (D3DVECTOR*) dnl// $4 - pointer to the input weights dnl// $5 - pointer to the input matrix indices (BYTE*) dnl// define(`d_TransformNormalToCameraSpace',`dnl d_empty_($1)// Transform vertex normal to the eye space d_margin($1)// We use inverse transposed matrix d_margin($1)if (pv->dwNumVerBlends == 0) d_margin($1){ d_margin($1) $3->x = $2->x*pv->mWVI[0]._11 + $2->y*pv->mWVI[0]._12 + $2->z*pv->mWVI[0]._13; d_margin($1) $3->y = $2->x*pv->mWVI[0]._21 + $2->y*pv->mWVI[0]._22 + $2->z*pv->mWVI[0]._23; d_margin($1) $3->z = $2->x*pv->mWVI[0]._31 + $2->y*pv->mWVI[0]._32 + $2->z*pv->mWVI[0]._33; d_margin($1)} d_margin($1)else d_margin($1){ d_margin($1) D3DVALUE* pWeight = (D3DVALUE*)($4); d_margin($1) D3DVALUE weight = 0; d_margin($1) $3->x = 0; d_margin($1) $3->y = 0; d_margin($1) $3->z = 0; d_margin($1) for (DWORD i=0; i <= pv->dwNumWeights; i++) d_margin($1) { d_margin($1) D3DVALUE t; d_margin($1) if (i == pv->dwNumWeights) d_margin($1) t = 1.0f - weight; d_margin($1) else d_margin($1) { d_margin($1) t = pWeight[i]; d_margin($1) weight += t; d_margin($1) } d_margin($1) D3DMATRIXI *m = pv->GetMatrixWVI(($5)[i]); d_margin($1) $3->x += ($2->x*m->_11 + $2->y*m->_12 + $2->z*m->_13) * t; d_margin($1) $3->y += ($2->x*m->_21 + $2->y*m->_22 + $2->z*m->_23) * t; d_margin($1) $3->z += ($2->x*m->_31 + $2->y*m->_32 + $2->z*m->_33) * t; d_margin($1) } d_margin($1)} d_margin($1)if (pv->dwDeviceFlags & D3DDEV_NORMALIZENORMALS) d_margin($1) VecNormalizeFast(*$3);') dnl dnl//-------------------------------------------------------------------------- dnl// d_ComputeClipCode dnl// Arguments: dnl// $1 - margin count dnl// x,y,z,w should be defined as float dnl// Output: dnl// clip should be defined as int dnl// define(`d_ComputeClipCode',`dnl d_empty_($1){ d_margin($1) D3DVALUE xx = w - x; d_margin($1) D3DVALUE yy = w - y; d_margin($1) D3DVALUE zz = w - z; d_margin($1) clip =((ASINT32(x) & 0x80000000) >> (32-D3DCS_LEFTBIT)) | d_margin($1) ((ASINT32(y) & 0x80000000) >> (32-D3DCS_BOTTOMBIT)) | d_margin($1) ((ASINT32(z) & 0x80000000) >> (32-D3DCS_FRONTBIT)) | d_margin($1) ((ASINT32(xx) & 0x80000000) >> (32-D3DCS_RIGHTBIT)) | d_margin($1) ((ASINT32(yy) & 0x80000000) >> (32-D3DCS_TOPBIT)) | d_margin($1) ((ASINT32(zz) & 0x80000000) >> (32-D3DCS_BACKBIT)); d_margin($1) if (pv->dwMaxUserClipPlanes) d_margin($1) { d_margin($1) DWORD dwClipBit = D3DCS_PLANE0; d_margin($1) for (DWORD i=0; i < pv->dwMaxUserClipPlanes; i++) d_margin($1) { d_margin($1) if (x*pv->userClipPlane[i].x + d_margin($1) y*pv->userClipPlane[i].y + d_margin($1) z*pv->userClipPlane[i].z + d_margin($1) w*pv->userClipPlane[i].w < 0) d_margin($1) { d_margin($1) clip |= dwClipBit; d_margin($1) } d_margin($1) dwClipBit <<= 1; d_margin($1) } d_margin($1) } d_margin($1)}') dnl dnl//-------------------------------------------------------------------------- dnl// d_ComputeClipCodeGB dnl// dnl// Arguments: dnl// $1 - margin count dnl// x,y,z,w should be defined as float dnl// Output: dnl// clip should be defined as int define(`d_ComputeClipCodeGB',`dnl d_empty_($1)// We do guardband check in the projection space, so d_margin($1)// we transform X and Y of the vertex there d_margin($1)D3DVALUE xnew = x * pv->vcache.gb11 + w * pv->vcache.gb41; d_margin($1)D3DVALUE ynew = y * pv->vcache.gb22 + w * pv->vcache.gb42; d_margin($1)D3DVALUE xx1 = w - xnew; d_margin($1)D3DVALUE yy1 = w - ynew; d_margin($1)clip |= ((ASINT32(xnew) & 0x80000000) >> (32-D3DCLIPGB_LEFTBIT)) | d_margin($1) ((ASINT32(ynew) & 0x80000000) >> (32-D3DCLIPGB_BOTTOMBIT)) | d_margin($1) ((ASINT32(xx1) & 0x80000000) >> (32-D3DCLIPGB_RIGHTBIT)) | d_margin($1) ((ASINT32(yy1) & 0x80000000) >> (32-D3DCLIPGB_TOPBIT));') dnl dnl//-------------------------------------------------------------------------- dnl// d_ComputeScreenCoordinatesNoOutput dnl// dnl// Computes screen coordinates dnl// Arguments: dnl// $1 - margin count dnl// $2 - x in the clipping space dnl// $3 - y in the clipping space dnl// $4 - z in the clipping space dnl// $5 - 1/w in the clipping space dnl// $6 - output1 x dnl// $7 - output1 y dnl// $8 - output1 z dnl// define(`d_ComputeScreenCoordinatesNoOutput',`dnl d_empty_($1)$6 = $2 * $5 * pv->vcache.scaleX + pv->vcache.offsetX; d_margin($1)$7 = $3 * $5 * pv->vcache.scaleY + pv->vcache.offsetY; d_margin($1)$8 = $4*pv->vcache.scaleZ*$5 + pv->vcache.offsetZ;') dnl dnl//-------------------------------------------------------------------------- dnl// d_ComputeScreenCoordinates dnl// dnl// Computes screen coordinates and output them dnl// Arguments: dnl// $1 - margin count dnl// $2 - x in the clipping space dnl// $3 - y in the clipping space dnl// $4 - z in the clipping space dnl// $5 - 1/w in the clipping space dnl// $6 - pointer to the D3DTLVERTEX (sx, sy, sz, rhw will be set dnl// dnl// Local variables x,y,z should be declared as float dnl// define(`d_ComputeScreenCoordinates',`dnl d_empty_($1)d_ComputeScreenCoordinatesNoOutput($1,$2,$3,$4,$5,x,y,z) d_margin($1)$6->sx = x; d_margin($1)$6->sy = y; d_margin($1)$6->sz = z; d_margin($1)$6->rhw = $5;') dnl dnl//--------------------------------------------------------------------- dnl// d_MakeOutputColors dnl// dnl// - Finishes computing of diffuse color, by computing emissive and ambient dnl// scene colors dnl// - Converts diffuse and specular colors to DWORDs and writes them to the dnl// d_dwOutDiffuse and d_dwOutSpecular dnl// dnl// $1 - margin count dnl// d_LightingFlags - DWORD dnl// d_OutDiffuse - temporary output diffuse color, (D3DFE_COLOR) dnl// d_OutSpecular - temporary output specular color, (D3DFE_COLOR) dnl// d_dwOutDiffuse - output diffuse color, (DWORD) dnl// d_dwOutSpecular - output specular color, (DWORD) dnl// define(`d_MakeOutputColors',`dnl d_empty_($1)if (pv->dwFlags & (D3DPV_COLORVERTEX_A | D3DPV_COLORVERTEX_E)) d_margin($1){ d_margin($1) if (!(d_LightingFlags & __LIGHT_DIFFUSECOMPUTED)) d_margin($1) { d_margin($1) d_OutDiffuse.r = 0; d_margin($1) d_OutDiffuse.g = 0; d_margin($1) d_OutDiffuse.b = 0; d_margin($1) } d_margin($1) if (pv->dwFlags & D3DPV_COLORVERTEX_A) d_margin($1) { d_margin($1) DWORD color = **ppAmbientSource; d_margin($1) d_OutDiffuse.r += RGBA_GETRED (color) * pv->lighting.ambientScene.r; d_margin($1) d_OutDiffuse.g += RGBA_GETGREEN(color) * pv->lighting.ambientScene.g; d_margin($1) d_OutDiffuse.b += RGBA_GETBLUE (color) * pv->lighting.ambientScene.b; d_margin($1) } d_margin($1) else d_margin($1) { d_margin($1) d_OutDiffuse.r += pv->lighting.ambientSceneScaled.r * pv->lighting.material.Ambient.r; d_margin($1) d_OutDiffuse.g += pv->lighting.ambientSceneScaled.g * pv->lighting.material.Ambient.g; d_margin($1) d_OutDiffuse.b += pv->lighting.ambientSceneScaled.b * pv->lighting.material.Ambient.b; d_margin($1) } d_margin($1) if (pv->dwFlags & D3DPV_COLORVERTEX_E) d_margin($1) { d_margin($1) DWORD color = **ppEmissiveSource; d_margin($1) d_OutDiffuse.r += RGBA_GETRED (color); d_margin($1) d_OutDiffuse.g += RGBA_GETGREEN(color); d_margin($1) d_OutDiffuse.b += RGBA_GETBLUE (color); d_margin($1) } d_margin($1) else d_margin($1) { d_margin($1) d_OutDiffuse.r += pv->lighting.material.Emissive.r * D3DVAL(255); d_margin($1) d_OutDiffuse.g += pv->lighting.material.Emissive.g * D3DVAL(255); d_margin($1) d_OutDiffuse.b += pv->lighting.material.Emissive.b * D3DVAL(255); d_margin($1) } d_margin($1) d_LightingFlags |= __LIGHT_DIFFUSECOMPUTED; d_margin($1)} d_margin($1)if (d_LightingFlags & __LIGHT_DIFFUSECOMPUTED) d_margin($1){ d_margin($1) if (!(pv->dwFlags & (D3DPV_COLORVERTEX_A | D3DPV_COLORVERTEX_E))) d_margin($1) { d_margin($1) d_OutDiffuse.r += pv->lighting.diffuse0.r; d_margin($1) d_OutDiffuse.g += pv->lighting.diffuse0.g; d_margin($1) d_OutDiffuse.b += pv->lighting.diffuse0.b; d_margin($1) } d_margin($1) int r = FTOI(d_OutDiffuse.r); d_margin($1) int g = FTOI(d_OutDiffuse.g); d_margin($1) int b = FTOI(d_OutDiffuse.b); d_margin($1) if (r < 0) r = 0; else if (r > 255) r = 255; d_margin($1) if (g < 0) g = 0; else if (g > 255) g = 255; d_margin($1) if (b < 0) b = 0; else if (b > 255) b = 255; d_margin($1) if (!(pv->dwFlags & D3DPV_COLORVERTEX_D)) d_margin($1) d_dwOutDiffuse = pv->lighting.alpha + (r<<16) + (g<<8) + b; d_margin($1) else d_margin($1) d_dwOutDiffuse = (**ppDiffuseSource & 0xFF000000) + (r<<16) + (g<<8) + b; d_margin($1)} d_margin($1)else d_margin($1){ d_margin($1) if (!(pv->dwFlags & D3DPV_COLORVERTEX_D)) d_margin($1) d_dwOutDiffuse = pv->lighting.alpha + pv->lighting.dwDiffuse0; d_margin($1) else d_margin($1) d_dwOutDiffuse = pv->lighting.dwDiffuse0 + (**ppDiffuseSource & 0xFF000000); d_margin($1)} d_margin($1) d_margin($1)if (d_LightingFlags & __LIGHT_SPECULARCOMPUTED) d_margin($1){ d_margin($1) int r = FTOI(d_OutSpecular.r); d_margin($1) int g = FTOI(d_OutSpecular.g); d_margin($1) int b = FTOI(d_OutSpecular.b); d_margin($1) if (r < 0) r = 0; else if (r > 255) r = 255; d_margin($1) if (g < 0) g = 0; else if (g > 255) g = 255; d_margin($1) if (b < 0) b = 0; else if (b > 255) b = 255; d_margin($1) if (!(pv->dwFlags & D3DPV_COLORVERTEX_S)) d_margin($1) d_dwOutSpecular = pv->lighting.alphaSpecular + (r<<16) + (g<<8) + b; d_margin($1) else d_margin($1) d_dwOutSpecular = (**ppSpecularSource & 0xFF000000) + (r<<16) + (g<<8) + b; d_margin($1)} d_margin($1)else d_margin($1)if (!(pv->dwFlags & D3DPV_DONOTCOPYSPECULAR)) d_margin($1){ d_margin($1) if (!(pv->dwDeviceFlags & D3DDEV_SPECULARENABLE)) d_margin($1) if (pv->dwVIDIn & D3DFVF_SPECULAR) d_margin($1) d_dwOutSpecular = *inSpecular; d_margin($1) else d_margin($1) d_dwOutSpecular = __DEFAULT_SPECULAR; d_margin($1) else d_margin($1) if (!(pv->dwFlags & D3DPV_COLORVERTEX_S)) d_margin($1) d_dwOutSpecular = pv->lighting.alphaSpecular; d_margin($1) else d_margin($1) d_dwOutSpecular = (**ppSpecularSource & 0xFF000000); d_margin($1)}') dnl//--------------------------------------------------------------------- dnl// d_MakeOutputColorsNoColorVertex dnl// dnl// - Finishes computing of diffuse color, by computing emissive and ambient dnl// scene colors dnl// - Converts diffuse and specular colors to DWORDs and writes them to the dnl// d_dwOutDiffuse and d_dwOutSpecular dnl// dnl// $1 - margin count dnl// d_LightingFlags - DWORD dnl// d_OutDiffuse - temporary output diffuse color, (D3DFE_COLOR) dnl// d_OutSpecular - temporary output specular color, (D3DFE_COLOR) dnl// d_dwOutDiffuse - output diffuse color, (DWORD) dnl// d_dwOutSpecular - output specular color, (DWORD) dnl// define(`d_MakeOutputColorsNoColorVertex',`dnl d_margin($1)if (d_LightingFlags & __LIGHT_DIFFUSECOMPUTED) d_margin($1){ d_margin($1) d_OutDiffuse.r += pv->lighting.diffuse0.r; d_margin($1) d_OutDiffuse.g += pv->lighting.diffuse0.g; d_margin($1) d_OutDiffuse.b += pv->lighting.diffuse0.b; d_margin($1) int r = FTOI(d_OutDiffuse.r); d_margin($1) int g = FTOI(d_OutDiffuse.g); d_margin($1) int b = FTOI(d_OutDiffuse.b); d_margin($1) if (r < 0) r = 0; else if (r > 255) r = 255; d_margin($1) if (g < 0) g = 0; else if (g > 255) g = 255; d_margin($1) if (b < 0) b = 0; else if (b > 255) b = 255; d_margin($1) d_dwOutDiffuse = pv->lighting.alpha + (r<<16) + (g<<8) + b; d_margin($1)} d_margin($1)else d_margin($1){ d_margin($1) d_dwOutDiffuse = pv->lighting.alpha + pv->lighting.dwDiffuse0; d_margin($1)} d_margin($1) d_margin($1)if (d_LightingFlags & __LIGHT_SPECULARCOMPUTED) d_margin($1){ d_margin($1) int r = FTOI(d_OutSpecular.r); d_margin($1) int g = FTOI(d_OutSpecular.g); d_margin($1) int b = FTOI(d_OutSpecular.b); d_margin($1) if (r < 0) r = 0; else if (r > 255) r = 255; d_margin($1) if (g < 0) g = 0; else if (g > 255) g = 255; d_margin($1) if (b < 0) b = 0; else if (b > 255) b = 255; d_margin($1) d_dwOutSpecular = pv->lighting.alphaSpecular + (r<<16) + (g<<8) + b; d_margin($1)} d_margin($1)else d_margin($1)if (!(pv->dwFlags & D3DPV_DONOTCOPYSPECULAR)) d_margin($1){ d_margin($1) if (!(pv->dwDeviceFlags & D3DDEV_SPECULARENABLE)) d_margin($1) if (pv->dwVIDIn & D3DFVF_SPECULAR) d_margin($1) d_dwOutSpecular = *inSpecular; d_margin($1) else d_margin($1) d_dwOutSpecular = __DEFAULT_SPECULAR; d_margin($1) else d_margin($1) d_dwOutSpecular = pv->lighting.alphaSpecular; d_margin($1)}') dnl//-------------------------------------------------------------------------- dnl// d_ComputeOutputColors dnl// dnl// Compute lighting and fog for a vertex dnl// dnl// Arguments: dnl// $1 - margin count dnl// $2 - pointer to the vertex coordinates dnl// $3 - pointer to the vertex normal dnl// $4 - pointer to the diffuse vertex color (used when there is no lighting) dnl// $5 - pointer to the specular vertex color (used when there is no lighting) dnl// $6 - pointer to the input vertex weights dnl// $7 - pointer to the input matrix indices dnl// Output: dnl// vertex diffuse and specular colors in the pv->lighting dnl// dnl define(`d_dwOutDiffuse',pv->lighting.outDiffuse)dnl define(`d_dwOutSpecular',pv->lighting.outSpecular)dnl define(`d_OutDiffuse',pv->lighting.diffuse)dnl define(`d_OutSpecular',pv->lighting.specular)dnl define(`d_LightingFlags',pv->lighting.dwLightingFlags)dnl dnl define(`d_ComputeOutputColors',`dnl d_empty_($1)pv->lighting.dwLightingFlags = 0; d_margin($1)if (pv->dwDeviceFlags & D3DDEV_POSITIONINCAMERASPACE) d_margin($1){ d_margin($1) d_TransformVertexToCameraSpace($1+1, $2, ((D3DVERTEX*)&EyeSpaceData.dvPosition), $6, $7) d_margin($1) pv->lighting.dwLightingFlags |= __LIGHT_VERTEXTRANSFORMED; d_margin($1)} d_margin($1)if (pv->dwDeviceFlags & D3DDEV_NORMALINCAMERASPACE) d_margin($1){ d_margin($1) d_TransformNormalToCameraSpace($1+1, inNormal, ((D3DVECTOR*)&EyeSpaceData.dvNormal), $6, $7) d_margin($1) pv->lighting.dwLightingFlags |= __LIGHT_NORMALTRANSFORMED; d_margin($1)} d_margin($1)if (pv->dwFlags & D3DPV_LIGHTING) d_margin($1){ d_margin($1) pv->lighting.diffuse.r = 0; d_margin($1) pv->lighting.diffuse.g = 0; d_margin($1) pv->lighting.diffuse.b = 0; d_margin($1) pv->lighting.specular.r = 0; d_margin($1) pv->lighting.specular.g = 0; d_margin($1) pv->lighting.specular.b = 0; d_margin($1) if (pv->dwFlags & D3DPV_DOCOLORVERTEX) d_margin($1) { d_margin($1) if (pv->dwFlags & D3DPV_COLORVERTEX_A) d_margin($1) pv->lighting.vertexAmbient = **ppAmbientSource; d_margin($1) if (pv->dwFlags & D3DPV_COLORVERTEX_D) d_margin($1) pv->lighting.vertexDiffuse = **ppDiffuseSource; d_margin($1) if (pv->dwFlags & D3DPV_COLORVERTEX_S) d_margin($1) pv->lighting.vertexSpecular = **ppSpecularSource; d_margin($1) } d_margin($1) D3DI_LIGHT *light = pv->lighting.activeLights; d_margin($1) while (light) d_margin($1) { d_margin($1) (*light->lightVertexFunc)(pv, light, (D3DVERTEX*)$2, $6, $7, $3, &EyeSpaceData); d_margin($1) light = light->next; d_margin($1) } d_margin($1) d_MakeOutputColors($1+1) d_margin($1)} d_margin($1)else d_margin($1)if (pv->dwVIDIn & (D3DFVF_DIFFUSE | D3DFVF_SPECULAR)) d_margin($1){ d_margin($1) if (pv->dwVIDIn & D3DFVF_DIFFUSE) d_margin($1) pv->lighting.outDiffuse = *(DWORD*)($4); d_margin($1) if (pv->dwVIDIn & D3DFVF_SPECULAR) d_margin($1) pv->lighting.outSpecular = *(DWORD*)($5); d_margin($1)} d_margin($1)if (pv->dwFlags & D3DPV_FOG) d_margin($1){ d_margin($1) ComputeFog(pv, *(D3DVECTOR*)($2), &EyeSpaceData.dvPosition, $6, $7); d_margin($1)}') dnl dnl//-------------------------------------------------------------------------- dnl// d_DoLightingAndFog dnl// dnl// Arguments: dnl// $1 - margin count dnl// $2 - pointer to the vertex coordinates dnl// $3 - pointer to the vertex normal dnl// $4 - pointer to the diffuse vertex color (used when there is no lighting) dnl// $5 - pointer to the specular vertex color (used when there is no lighting) dnl// $6 - pointer to output vertex dnl// $7 - pointer to input vertex weights dnl// $8 - pointer to input matrix indices dnl// Output: dnl// vertex diffuse and specular colors in the pv->lighting dnl// Pointer to the output will be moved to the next DWORD dnl// define(`d_DoLightingAndFog',`dnl d_empty_($1)d_ComputeOutputColors($1, $2, $3, $4, $5, $7, $8) d_margin($1)if (!(pv->dwFlags & D3DPV_DONOTCOPYDIFFUSE)) d_margin($1) *(DWORD*)((BYTE*)$6 + pv->diffuseOffsetOut) = pv->lighting.outDiffuse; d_margin($1)if (!(pv->dwFlags & D3DPV_DONOTCOPYSPECULAR)) d_margin($1) *(DWORD*)((BYTE*)$6 + pv->specularOffsetOut) = pv->lighting.outSpecular;') dnl dnl//-------------------------------------------------------------------------- dnl// d_CopyTextureCoordStrided dnl// dnl// Copies texture coordinates from input to the output dnl// $1 - margin count dnl// $2 - pointer to the output texture dnl// define(`d_CopyTextureCoordStrided',`dnl d_empty_($1)D3DVALUE *_pOut = (D3DVALUE*)$2; d_margin($1)if (!(pv->dwDeviceFlags & (D3DDEV_TEXTURETRANSFORM | D3DDEV_REMAPTEXTUREINDICES))) d_margin($1){ d_margin($1) for (DWORD k=0; k < pv->nOutTexCoord; k++) d_margin($1) { d_margin($1) const DWORD dwSize = pv->dwTextureCoordSize[k]; d_margin($1) memcpy(_pOut, inTexture[k], dwSize); d_margin($1) NEXT(_pOut, dwSize, D3DVALUE); d_margin($1) } d_margin($1)} d_margin($1)else d_margin($1)if (!(pv->dwDeviceFlags & D3DDEV_REMAPTEXTUREINDICES)) d_margin($1){ d_margin($1) for (DWORD k=0; k < pv->nOutTexCoord; k++) d_margin($1) { d_margin($1) const DWORD dwSize = pv->dwTextureCoordSize[k]; d_margin($1) const DWORD dwInpSize = pv->dwInpTextureCoordSize[k]; d_margin($1) if (pv->pmTexture[k] == 0) d_margin($1) memcpy(_pOut, inTexture[k], dwSize); d_margin($1) else d_margin($1) { d_margin($1) const DWORD m = dwInpSize >> 2; // Number of input tex. coord. d_margin($1) const DWORD n = dwSize >> 2; // Number of output tex. coord. d_margin($1) (*(g_pfnTextureTransform[MakeTexTransformFuncIndex(m ,n)])) d_margin($1) (inTexture[k], _pOut, pv->pmTexture[k]); d_margin($1) } d_margin($1) NEXT(_pOut, dwSize, D3DVALUE); d_margin($1) } d_margin($1)} d_margin($1)else d_margin($1){ d_margin($1) D3DVALUE *_pOut = (D3DVALUE*)$2; d_margin($1) D3DVECTOR reflectionVector; d_margin($1) for (DWORD i=0; i < pv->dwNumTextureStages; i++) d_margin($1) { d_margin($1) LPD3DFE_TEXTURESTAGE pStage = &pv->textureStage[i]; d_margin($1) DWORD dwInpIndex = pStage->dwInpCoordIndex; d_margin($1) D3DVALUE *_pIn; d_margin($1) if (pStage->dwTexGenMode == 0) d_margin($1) _pIn = inTexture[dwInpIndex]; d_margin($1) else d_margin($1) if (pStage->dwTexGenMode == D3DTSS_TCI_CAMERASPACEPOSITION) d_margin($1) _pIn = (D3DVALUE*)&EyeSpaceData.dvPosition; d_margin($1) else d_margin($1) if (pStage->dwTexGenMode == D3DTSS_TCI_CAMERASPACENORMAL) d_margin($1) _pIn = (D3DVALUE*)&EyeSpaceData.dvNormal; d_margin($1) else // D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR d_margin($1) { d_margin($1) if (pv->dwDeviceFlags & D3DDEV_LOCALVIEWER) d_margin($1) ComputeReflectionVector((D3DVECTOR*)&EyeSpaceData.dvPosition, d_margin($1) (D3DVECTOR*)&EyeSpaceData.dvNormal, d_margin($1) &reflectionVector); d_margin($1) else d_margin($1) ComputeReflectionVectorInfiniteViewer((D3DVECTOR*)&EyeSpaceData.dvNormal, d_margin($1) &reflectionVector); d_margin($1) d_margin($1) _pIn = (D3DVALUE*)&reflectionVector; d_margin($1) } d_margin($1) DWORD dwSize = pv->dwTextureCoordSize[i]; d_margin($1) if (pStage->bDoTextureProjection) d_margin($1) { d_margin($1) // We need to do emulation of texture projection d_margin($1) d_margin($1) if (pStage->pmTextureTransform == NULL) d_margin($1) { d_margin($1) DoTextureProjection(_pIn, _pOut, dwSize); d_margin($1) } d_margin($1) else d_margin($1) { d_margin($1) float TmpOutputTexture[4]; d_margin($1) (*(g_pfnTextureTransform[pStage->dwTexTransformFuncIndex])) d_margin($1) (_pIn, TmpOutputTexture, pStage->pmTextureTransform); d_margin($1) DoTextureProjection(TmpOutputTexture, _pOut, dwSize); d_margin($1) } d_margin($1) } d_margin($1) else d_margin($1) if (pStage->pmTextureTransform) d_margin($1) { d_margin($1) (*(g_pfnTextureTransform[pStage->dwTexTransformFuncIndex]))(_pIn, _pOut, d_margin($1) pStage->pmTextureTransform); d_margin($1) } d_margin($1) else d_margin($1) { d_margin($1) memcpy(_pOut, _pIn, dwSize); d_margin($1) } d_margin($1) NEXT(_pOut, dwSize, D3DVALUE); d_margin($1) } d_margin($1)}') dnl dnl//-------------------------------------------------------------------------- dnl// d_CopyTextureCoordFVF dnl// dnl// Copies texture coordinates from input to the output dnl// $1 - margin count dnl// $2 - pointer to the output vertex dnl// define(`d_CopyTextureCoordFVF',`dnl d_empty_($1) d_margin($1)if (!(pv->dwDeviceFlags & (D3DDEV_TEXTURETRANSFORM | D3DDEV_REMAPTEXTUREINDICES))) d_margin($1) memcpy($2, inTexture[0], pv->dwTextureCoordSizeTotal); d_margin($1)else d_margin($1)if (!(pv->dwDeviceFlags & D3DDEV_REMAPTEXTUREINDICES)) d_margin($1){ d_margin($1) D3DVALUE *_pIn = inTexture[0]; d_margin($1) D3DVALUE *_pOut = (D3DVALUE*)$2; d_margin($1) for (DWORD i=0; i < pv->nOutTexCoord; i++) d_margin($1) { d_margin($1) const DWORD dwSize = pv->dwTextureCoordSize[i]; d_margin($1) const DWORD dwInpSize = pv->dwInpTextureCoordSize[i]; d_margin($1) if (pv->pmTexture[i]) d_margin($1) { d_margin($1) const DWORD m = dwInpSize >> 2; // Number of input tex. coord. d_margin($1) const DWORD n = dwSize >> 2; // Number of output tex. coord. d_margin($1) (*(g_pfnTextureTransform[MakeTexTransformFuncIndex(m, n)])) d_margin($1) (_pIn, _pOut, pv->pmTexture[i]); d_margin($1) } d_margin($1) else d_margin($1) memcpy(_pOut, _pIn, dwSize); d_margin($1) NEXT(_pIn, dwInpSize, D3DVALUE); d_margin($1) NEXT(_pOut, dwSize, D3DVALUE); d_margin($1) } d_margin($1)} d_margin($1)else d_margin($1){ d_margin($1) D3DVALUE *_pOut = (D3DVALUE*)$2; d_margin($1) D3DVECTOR reflectionVector; d_margin($1) for (DWORD i=0; i < pv->dwNumTextureStages; i++) d_margin($1) { d_margin($1) LPD3DFE_TEXTURESTAGE pStage = &pv->textureStage[i]; d_margin($1) D3DVALUE *_pIn; d_margin($1) if (pStage->dwTexGenMode == 0) d_margin($1) _pIn = (D3DVALUE*)((BYTE*)inTexture[0] + pStage->dwInpOffset); d_margin($1) else d_margin($1) if (pStage->dwTexGenMode == D3DTSS_TCI_CAMERASPACEPOSITION) d_margin($1) _pIn = (D3DVALUE*)&EyeSpaceData.dvPosition; d_margin($1) else d_margin($1) if (pStage->dwTexGenMode == D3DTSS_TCI_CAMERASPACENORMAL) d_margin($1) _pIn = (D3DVALUE*)&EyeSpaceData.dvNormal; d_margin($1) else // D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR d_margin($1) { d_margin($1) if (pv->dwDeviceFlags & D3DDEV_LOCALVIEWER) d_margin($1) ComputeReflectionVector((D3DVECTOR*)&EyeSpaceData.dvPosition, d_margin($1) (D3DVECTOR*)&EyeSpaceData.dvNormal, d_margin($1) &reflectionVector); d_margin($1) else d_margin($1) ComputeReflectionVectorInfiniteViewer((D3DVECTOR*)&EyeSpaceData.dvNormal, d_margin($1) &reflectionVector); d_margin($1) _pIn = (D3DVALUE*)&reflectionVector; d_margin($1) } d_margin($1) DWORD dwSize = pv->dwTextureCoordSize[i]; d_margin($1) if (pStage->bDoTextureProjection) d_margin($1) { d_margin($1) // We need to do emulation of texture projection d_margin($1) d_margin($1) if (pStage->pmTextureTransform == NULL) d_margin($1) { d_margin($1) DoTextureProjection(_pIn, _pOut, dwSize); d_margin($1) } d_margin($1) else d_margin($1) { d_margin($1) float TmpOutputTexture[4]; d_margin($1) (*(g_pfnTextureTransform[pStage->dwTexTransformFuncIndex])) d_margin($1) (_pIn, TmpOutputTexture, pStage->pmTextureTransform); d_margin($1) DoTextureProjection(TmpOutputTexture, _pOut, dwSize); d_margin($1) } d_margin($1) } d_margin($1) else d_margin($1) if (pStage->pmTextureTransform) d_margin($1) { d_margin($1) (*(g_pfnTextureTransform[pStage->dwTexTransformFuncIndex])) d_margin($1) (_pIn, _pOut, pStage->pmTextureTransform); d_margin($1) } d_margin($1) else d_margin($1) { d_margin($1) memcpy(_pOut, _pIn, dwSize); d_margin($1) } d_margin($1) NEXT(_pOut, dwSize, D3DVALUE); d_margin($1) } d_margin($1)}') dnl dnl//-------------------------------------------------------------------------- dnl// d_CopyTextureCoord dnl// dnl// Copies texture coordinates from input to the output dnl// $1 - margin count dnl// $2 - pointer to the output vertex dnl// define(`d_CopyTextureCoord',`dnl d_empty_($1)if (!(pv->dwFlags & D3DPV_DONOTCOPYTEXTURE)) d_margin($1){ d_margin($1) if (pv->dwDeviceFlags & D3DDEV_STRIDE) d_margin($1) { d_margin($1) d_CopyTextureCoordStrided($1+2, $2) d_margin($1) } d_margin($1) else d_margin($1) { d_margin($1) d_CopyTextureCoordFVF($1+2, $2) d_margin($1) } d_margin($1)}') dnl dnl//------------------------------------------------------------------ dnl// Setup pointers and flags before processing a primitive or vertices dnl// dnl// define(`d_Setup',` DWORD dwOutVerSize = pv->dwOutputSize; DWORD dwClipIntersection; DWORD dwClipUnion; DWORD inVID = pv->dwVIDIn; DWORD outVID = pv->dwVIDOut; DWORD dwDeviceFlags = pv->dwDeviceFlags; D3DVECTOR *in; // Input position pointer D3DVECTOR *in2 = NULL; // Input position2 pointer D3DVALUE *inWeights; D3DVECTOR *inNormal; D3DVECTOR *inNormal2 = NULL; float *inPointSize; BYTE *inMatrixIndices; union { DWORD colors[2]; struct { DWORD *inDiffuse; // inDiffuse and inSpecular should be in his order !!! DWORD *inSpecular; }; }; DWORD dwInpVerSize; // Position stride D3DVALUE *inTexture[8]; DWORD **ppEmissiveSource; // Used when COLORVERTEX_E is set DWORD **ppAmbientSource; // Used when COLORVERTEX_A is set DWORD **ppDiffuseSource; // Used when COLORVERTEX_D is set DWORD **ppSpecularSource; // Used when COLORVERTEX_S is set in = (D3DVECTOR*)pv->position.lpvData; dwInpVerSize = pv->position.dwStride; inTexture[0] = (D3DVALUE*)in; // For DONOTSTRIPELEMENTS we will copy XYZ to // the output texture coordinates, but it does not matter if (!(dwDeviceFlags & D3DDEV_STRIDE)) { inWeights = (D3DVALUE*) ((char*)in + 3*sizeof(float)); inNormal = (D3DVECTOR*) ((char*)in + pv->normalOffset); inDiffuse = (DWORD*) ((char*)in + pv->diffuseOffset); inSpecular = (DWORD*) ((char*)in + pv->specularOffset); inPointSize = (float*) ((char*)in + pv->pointSizeOffset); inMatrixIndices = (BYTE*)(inWeights + pv->dwNumWeights); if (pv->nTexCoord) inTexture[0] = (D3DVALUE*) ((char*)in + pv->texOffset); } else { inWeights = (D3DVALUE*)pv->weights.lpvData; inNormal = (D3DVECTOR*)pv->normal.lpvData; in2 = (D3DVECTOR*)pv->position2.lpvData; inNormal2 = (D3DVECTOR*)pv->normal2.lpvData; inDiffuse = (DWORD*)pv->diffuse.lpvData; inSpecular = (DWORD*)pv->specular.lpvData; inPointSize = (float*)pv->psize.lpvData; inMatrixIndices = (BYTE*)pv->matrixIndices.lpvData; for (DWORD i=0; i < pv->nTexCoord; i++) inTexture[i] = (D3DVALUE*)pv->textures[i].lpvData; } if (!(dwDeviceFlags & D3DDEV_INDEXEDVERTEXBLENDENABLE)) { inMatrixIndices = pv->MatrixIndices; pv->matrixIndices.dwStride = 0; } pv->lighting.outDiffuse = __DEFAULT_DIFFUSE; pv->lighting.outSpecular = __DEFAULT_SPECULAR; pv->lighting.dwLightingFlags = 0; if (pv->dwFlags & D3DPV_LIGHTING) { pv->lighting.diffuse = pv->lighting.diffuse0; pv->lighting.specular.r = D3DVAL(0); pv->lighting.specular.g = D3DVAL(0); pv->lighting.specular.b = D3DVAL(0); if (pv->dwDeviceFlags & D3DDEV_COLORVERTEX) { if (pv->dwVIDIn & D3DFVF_DIFFUSE) { if(pv->lighting.dwEmissiveSrcIndex == 0) { pv->dwFlags |= D3DPV_COLORVERTEX_E | D3DPV_DOCOLORVERTEX; ppEmissiveSource = &inDiffuse; } if(pv->lighting.dwDiffuseSrcIndex == 0) { pv->dwFlags |= D3DPV_COLORVERTEX_D | D3DPV_DOCOLORVERTEX; ppDiffuseSource = &inDiffuse; } if(pv->lighting.dwAmbientSrcIndex == 0) { pv->dwFlags |= D3DPV_COLORVERTEX_A | D3DPV_DOCOLORVERTEX; ppAmbientSource = &inDiffuse; } if(pv->lighting.dwSpecularSrcIndex == 0) { pv->dwFlags |= D3DPV_COLORVERTEX_S | D3DPV_DOCOLORVERTEX; ppSpecularSource = &inDiffuse; } } if (pv->dwVIDIn & D3DFVF_SPECULAR) { if(pv->lighting.dwEmissiveSrcIndex == 1) { pv->dwFlags |= D3DPV_COLORVERTEX_E | D3DPV_DOCOLORVERTEX; ppEmissiveSource = &inSpecular; } if(pv->lighting.dwDiffuseSrcIndex == 1) { pv->dwFlags |= D3DPV_COLORVERTEX_D | D3DPV_DOCOLORVERTEX; ppDiffuseSource = &inSpecular; } if(pv->lighting.dwAmbientSrcIndex == 1) { pv->dwFlags |= D3DPV_COLORVERTEX_A | D3DPV_DOCOLORVERTEX; ppAmbientSource = &inSpecular; } if(pv->lighting.dwSpecularSrcIndex == 1) { pv->dwFlags |= D3DPV_COLORVERTEX_S | D3DPV_DOCOLORVERTEX; ppSpecularSource = &inSpecular; } } } } dwClipUnion = 0; dwClipIntersection = 0; if (!(dwDeviceFlags & D3DDEV_DONOTCLIP)) dwClipIntersection = ~0;') dnl dnl//------------------------------------------------------------------ dnl// d_UpdateInputPointersStrided dnl// dnl// Updates input pointers dnl// dnl// Arguments: dnl// $1 - margin counter dnl// dnl// Notes: dnl// Output pointer is changed dnl// define(`d_UpdateInputPointersStrided',`dnl d_empty_($1){ d_margin($1) NEXT(in, dwInpVerSize, D3DVECTOR); d_margin($1) NEXT(inWeights, pv->weights.dwStride, D3DVALUE); d_margin($1) NEXT(inMatrixIndices, pv->matrixIndices.dwStride, BYTE); d_margin($1) NEXT(inPointSize, pv->psize.dwStride, float); d_margin($1) // This speeds up the xform only case d_margin($1) if (!(pv->dwFlags & D3DPV_TRANSFORMONLY)) d_margin($1) { d_margin($1) NEXT(inNormal, pv->normal.dwStride, D3DVECTOR); d_margin($1) NEXT(inDiffuse, pv->diffuse.dwStride, DWORD); d_margin($1) NEXT(inSpecular, pv->specular.dwStride, DWORD); d_margin($1) { d_margin($1) for (DWORD j=0; j < pv->nTexCoord; j++) d_margin($1) NEXT(inTexture[j], pv->textures[j].dwStride, D3DVALUE); d_margin($1) } d_margin($1) } d_margin($1)}') dnl dnl//------------------------------------------------------------------ dnl// d_UpdateInputPointersFVF dnl// dnl// Updates input pointers dnl// dnl// Arguments: dnl// $1 - margin counter dnl// $2 - how many vertices to skip dnl// dnl// Notes: dnl// Output pointer is changed dnl// define(`d_UpdateInputPointersFVF',`dnl d_empty_($1){ d_margin($1) NEXT(in, dwInpVerSize, D3DVECTOR); d_margin($1) NEXT(inWeights, dwInpVerSize, D3DVALUE); d_margin($1) NEXT(inPointSize, dwInpVerSize, float); d_margin($1) // When matrix indices are not present, dwStride is zero d_margin($1) NEXT(inMatrixIndices, pv->matrixIndices.dwStride, BYTE); d_margin($1) // This speeds up the xform only case d_margin($1) if (!(pv->dwFlags & D3DPV_TRANSFORMONLY)) d_margin($1) { d_margin($1) NEXT(inNormal, dwInpVerSize, D3DVECTOR); d_margin($1) NEXT(inDiffuse, dwInpVerSize, DWORD); d_margin($1) NEXT(inSpecular, dwInpVerSize, DWORD); d_margin($1) NEXT(inTexture[0], dwInpVerSize, D3DVALUE); d_margin($1) } d_margin($1)}') dnl dnl//------------------------------------------------------------------ dnl// d_CopyTextureCoordUpdateInputPointers dnl// dnl// Copies texture coordinates to the output and updates input pointers dnl// dnl// Arguments: dnl// $1 - margin counter dnl// $2 - pointer to the output texture dnl// dnl// Notes: dnl// Output pointer is changed dnl// define(`d_CopyTextureCoordUpdateInputPointers',`dnl d_empty_($1)if (pv->dwDeviceFlags & D3DDEV_STRIDE) d_margin($1){ d_margin($1) if (!(pv->dwFlags & D3DPV_DONOTCOPYTEXTURE)) d_margin($1) { d_margin($1) d_CopyTextureCoordStrided($1+2, $2) d_margin($1) } d_margin($1) d_UpdateInputPointersStrided($1+1) d_margin($1)} d_margin($1)else d_margin($1){ d_margin($1) if (!(pv->dwFlags & D3DPV_DONOTCOPYTEXTURE)) d_margin($1) { d_margin($1) d_CopyTextureCoordFVF($1+2, $2) d_margin($1) } d_margin($1) d_UpdateInputPointersFVF($1+1) d_margin($1)}') dnl dnl//------------------------------------------------------------------ dnl// d_UpdateInputPointers dnl// dnl// Updates input pointers dnl// dnl// Arguments: dnl// $1 - margin counter dnl// dnl// Notes: dnl// Output pointer is changed dnl// define(`d_UpdateInputPointers',`dnl d_empty_($1)if (pv->dwDeviceFlags & D3DDEV_STRIDE) d_margin($1){ d_margin($1) d_UpdateInputPointersStrided($1+1) d_margin($1)} d_margin($1)else d_margin($1){ d_margin($1) d_UpdateInputPointersFVF($1+1) d_margin($1)}') dnl