Water::Water(const std::string& name, const std::string& shaderName, int shaderID) : Grid(name, shaderName, shaderID), m_speed(1.0f), m_bump(1.0f), m_bumpScale(4.0f, 6.0f), m_uvScale(1.0f, 1.0f), m_fresnal(1.0f, 0.5f, 2.0f), m_shallowColour(1.0f, 1.0f, 1.0f, 0.5f), m_deepColour(0.8f, 0.8f, 0.8f, 1.0f), m_reflectionTint(1.0f, 1.0f, 1.0f, 1.0f), m_reflection(1.0f) { BackfaceCull(false); m_waves.resize(Wave::MAX); m_waves[0].amplitude = 1.0f; m_waves[0].frequency = 1.0f; m_waves[0].phase = 1.0f; m_waves[0].directionX = -1.0f; m_waves[0].directionZ = 0.0f; m_waves[1].amplitude = 0.5f; m_waves[1].frequency = 1.0f; m_waves[1].phase = 1.0f; m_waves[1].directionX = -0.7f; m_waves[1].directionZ = 0.7f; }
////////////////////////////////////////////////////////////////////////////// // // LightProjectClipXmm() // // works in model space with the old pipe // assumes SetupLightsModel has been called // if dstV and dstCount are non NULL bucket mem // void Camera::LightProjectClipXmm( Plane *srcP, Vector *srcVect, Vector *srcNorm, UVPair *srcUV, U32 countV, U16 *srcI, U32 countI, VertexTL **dstV, U32 *dstVCount, U32 *dstICount) // = NULL, = NULL, = NULL) { ASSERT( countI <= MAXINDICES); // temp pools : FIXME : eliminate temp copying U16 notCulledV[MAXVERTS]; static VertexTL litV_unaligned[MAXVERTS+1]; static VertexTL *litV = (VertexTL*) (((U32)litV_unaligned+0x0000000f) & 0xfffffff0); U16 litI[MAXINDICES]; BackfaceCull(srcP, notCulledV, countV, srcI, litI, countI); if (!countV) { // no forward faces if (dstV) { *dstV = NULL; *dstVCount = 0; *dstICount = 0; } return; } Material &material = *DxLight::Manager::curMaterial; Color diffa = (Color) Utils::FtoL( material.desc.diffuse.a * 255.0f) << 24; // calculate the parts of the diffuse color that are the same for all output vertexes ColorValueXmm diffInit; // FIXME: do we really want to ignore material ambient values (yes for DR2) // diffInit.r = curMaterial->desc.diffuse.r * Vid::renderState.ambientR + curMaterial->desc.emissive.r; // diffInit.g = curMaterial->desc.diffuse.g * Vid::renderState.ambientG + curMaterial->desc.emissive.g; // diffInit.b = curMaterial->desc.diffuse.b * Vid::renderState.ambientB + curMaterial->desc.emissive.b; diffInit.Set( Vid::renderState.ambientR + material.desc.emissive.r, Vid::renderState.ambientG + material.desc.emissive.g, Vid::renderState.ambientB + material.desc.emissive.b, material.desc.diffuse.a); const static __m128 zero = _mm_setzero_ps(); const static ColorValueXmm specInit(zero, zero, zero, _mm_set_ps1(1.0f)); // make the count a multiple of four by lighting the last vert multiple times notCulledV[countV+0] = notCulledV[countV+1] = notCulledV[countV+2] = notCulledV[countV+3] = notCulledV[countV-1]; U32 countV_rem = ((4 - (countV % SIMD_WIDTH)) << 30) >> 30; countV += countV_rem; ASSERT( (countV % SIMD_WIDTH) == 0 ); U8 clip_flags[MAXVERTS]; for ( U32 vc = 0; vc < countV; vc += SIMD_WIDTH ) { // set-up xmm vertex U16 i0 = notCulledV[vc+0], i1 = notCulledV[vc+1], i2 = notCulledV[vc+2], i3 = notCulledV[vc+3]; VertexXmm vert; vert.V0 = _mm_loadu_ps(&srcVect[i0]); vert.V1 = _mm_loadu_ps(&srcVect[i1]); vert.V2 = _mm_loadu_ps(&srcVect[i2]); vert.V3 = _mm_loadu_ps(&srcVect[i3]); __m128 lit[4]; SetHomogeneousFromModelXmm(lit, &vert.V0); // generate clip flags const static U32 pos_w_mask_U32 = 0x7fffffff, neg_w_mask_U32 = 0x80000000; const static __m128 pos_w_mask = _mm_set_ps1(*((F32*) &pos_w_mask_U32)), neg_w_mask = _mm_set_ps1(*((F32*) &neg_w_mask_U32)); __m128 neg_w, pos_w; #define COMPUTE_SUTHERLAND(i) \ { \ pos_w = _mm_and_ps(pos_w_mask, _mm_shuffle_ps(lit[(i)], lit[(i)], 0xff)); \ neg_w = _mm_or_ps (neg_w_mask, pos_w); \ clip_flags[vc+(i)] = 0; \ clip_flags[vc+(i)] |= (U8) (_mm_movemask_ps(_mm_cmplt_ps(lit[(i)], neg_w))); \ clip_flags[vc+(i)] << 4; \ clip_flags[vc+(i)] |= (U8) (_mm_movemask_ps(_mm_cmplt_ps(pos_w, lit[(i)]))); \ clip_flags[vc+(i)] &= 0x77; \ } COMPUTE_SUTHERLAND(0); COMPUTE_SUTHERLAND(1); COMPUTE_SUTHERLAND(2); COMPUTE_SUTHERLAND(3); TRANSPOSE_4X4(vert.V0, vert.V1, vert.V2, vert.V3); vert.NV.Set(srcNorm[i0], srcNorm[i1], srcNorm[i2], srcNorm[i3]); vert.DIFFUSE = diffInit; vert.SPECULAR = specInit; // light four verts DxLight::Manager::LightModel(vert, material); VertexTL &out0 = litV[vc+0], &out1 = litV[vc+1], &out2 = litV[vc+2], &out3 = litV[vc+3]; _mm_storeu_ps(&out0, lit[0]); _mm_storeu_ps(&out1, lit[1]); _mm_storeu_ps(&out2, lit[2]); _mm_storeu_ps(&out3, lit[3]); vert.DIFFUSE.GetRGBA (out0.diffuse, out1.diffuse, out2.diffuse, out3.diffuse ); vert.SPECULAR.GetRGBA(out0.specular, out1.specular, out2.specular, out3.specular); out0.uv = srcUV[i0]; out1.uv = srcUV[i1]; out2.uv = srcUV[i2]; out3.uv = srcUV[i3]; } countV -= countV_rem; ClipToBucket( litV, countV, litI, countI, clip_flags, dstV, dstVCount, dstICount); }
////////////////////////////////////////////////////////////////////////////// // // LightProjectNoClipXmm() // void Camera::LightProjectNoClipXmm( Plane *srcP, Vector *srcVect, Vector *srcNorm, UVPair *srcUV, U32 countV, U16 *srcI, U32 countI, VertexTL **dstV, U32 *dstVCount, U32 *dstICount) // = NULL, = NULL, = NULL) { if (dstV) { // in case we exit before bottom *dstV = NULL; *dstVCount = 0; *dstICount = 0; } ASSERT( countI <= MAXINDICES); U16 notCulledV[MAXVERTS]; static VertexTL *litV; U16 *litI; // This is called before BackfaceCull only because we don't know the countI. // We may want to try to put litI in a temporary buffer during backface cull // and then allocate bucket mem after BackfaceCull. // This works for now. if (!Vid::LockIndexedPrimitiveMem( (void **)&litV, countV, &litI, countI)) { return; } #ifdef _DEBUG U32 orig_countV = countV; // used in ASSERT below #endif BackfaceCull(srcP, notCulledV, countV, srcI, litI, countI); if (!countV) { // no forward faces Vid::UnlockIndexedPrimitiveMem( 0, 0, FALSE, TRUE); return; } // make the count a multiple of four by lighting the last vert multiple times notCulledV[countV+0] = notCulledV[countV+1] = notCulledV[countV+2] = notCulledV[countV+3] = notCulledV[countV-1]; U32 countV_rem = ((4 - (countV % SIMD_WIDTH)) << 30) >> 30; countV += countV_rem; ASSERT( countV <= orig_countV ); ASSERT( (countV % SIMD_WIDTH) == 0 ); Material &material = *DxLight::Manager::curMaterial; U32 diffa = Utils::FtoL( material.desc.diffuse.a * 255.0f); // calculate the parts of the diffuse color that are the same for all output vertexes ColorValueXmm diffInit; // FIXME: do we really want to ignore material ambient values (yes for DR2) #ifdef DOBZ2 diffInit.Set( material->desc.diffuse.r * Vid::renderState.ambientR + mateial->desc.emissive.r, material->desc.diffuse.g * Vid::renderState.ambientG + mateial->desc.emissive.g, material->desc.diffuse.b * Vid::renderState.ambientB + mateial->desc.emissive.b, material.desc.diffuse.a); #else diffInit.Set( Vid::renderState.ambientR + material.desc.emissive.r, Vid::renderState.ambientG + material.desc.emissive.g, Vid::renderState.ambientB + material.desc.emissive.b, material.desc.diffuse.a); #endif const static __m128 zero = _mm_setzero_ps(); const static ColorValueXmm specInit(zero, zero, zero, _mm_set_ps1(1.0f)); for ( U32 vc = 0; vc < countV; vc += SIMD_WIDTH ) { // set-up xmm vertex U16 i0 = notCulledV[vc+0], i1 = notCulledV[vc+1], i2 = notCulledV[vc+2], i3 = notCulledV[vc+3]; VertexXmm vert; vert.V0 = _mm_loadu_ps(&srcVect[i0]); vert.V1 = _mm_loadu_ps(&srcVect[i1]); vert.V2 = _mm_loadu_ps(&srcVect[i2]); vert.V3 = _mm_loadu_ps(&srcVect[i3]); // need to add function: TransformProjectModelXmm() __m128 lit[4]; SetHomogeneousFromModelXmm(lit, &vert.V0); TRANSPOSE_4X4(vert.V0, vert.V1, vert.V2, vert.V3); vert.NV.Set(srcNorm[i0], srcNorm[i1], srcNorm[i2], srcNorm[i3]); vert.DIFFUSE = diffInit; vert.SPECULAR = specInit; // light four verts DxLight::Manager::LightModel(vert, material); VertexTL &out0 = litV[vc+0], &out1 = litV[vc+1], &out2 = litV[vc+2], &out3 = litV[vc+3]; _mm_storeu_ps(&out0, lit[0]); _mm_storeu_ps(&out1, lit[1]); _mm_storeu_ps(&out2, lit[2]); _mm_storeu_ps(&out3, lit[3]); vert.DIFFUSE.GetRGBA (out0.diffuse, out1.diffuse, out2.diffuse, out3.diffuse ); vert.SPECULAR.GetRGBA(out0.specular, out1.specular, out2.specular, out3.specular); out0.uv = srcUV[i0]; out1.uv = srcUV[i1]; out2.uv = srcUV[i2]; out3.uv = srcUV[i3]; ProjectFromHomogeneousXmm(out0); ProjectFromHomogeneousXmm(out1); ProjectFromHomogeneousXmm(out2); ProjectFromHomogeneousXmm(out3); } countV -= countV_rem; if (dstV) { // pass back to caller *dstV = litV; *dstVCount = countV; *dstICount = countI; } else { Vid::UnlockIndexedPrimitiveMem( countV, countI, FALSE, TRUE); } }