void UVW_ChannelClass::ResolveOldData(UVW_ChannelClass &oldData) { if (oldData.f.Count() == f.Count()) { BOOL bail = FALSE; //make sure similiar topology for (int i = 0; i < f.Count();i++) { int degree = f[i]->count; int oldDegree = oldData.f[i]->count; if (oldDegree != degree) bail = TRUE; } if (!bail) { //copy the face data for (int i = 0; i < f.Count();i++) { int degree = f[i]->count; UVW_TVFaceClass *holdFace = f[i]; f[i] = oldData.f[i]->Clone(); for (int j = 0; j < degree; j++) f[i]->v[j] = holdFace->v[j]; if (f[i]->vecs) { for (int j = 0; j < 8; j++) f[i]->vecs->vhandles[j] = holdFace->vecs->vhandles[j]; for (int j = 0; j < 4; j++) f[i]->vecs->vinteriors[j] = holdFace->vecs->vinteriors[j]; } delete holdFace; } //copy the vertex data v.SetCount(oldData.v.Count()); for (int i = 0; i < oldData.v.Count();i++) { v[i] = oldData.v[i]; } BuildEdges(); } } }
void UVW_ChannelClass::SplitUVEdges(BitArray esel) { //get our point selection from the edges BitArray pointSel; pointSel.SetSize(v.Count()); pointSel.ClearAll(); for (int i = 0; i < ePtrList.Count(); i++) { if (esel[i]) { int a = ePtrList[i]->a; int b = ePtrList[i]->b; pointSel.Set(a,TRUE); pointSel.Set(b,TRUE); } } //build a lis of egdes for each vert Tab<VEdges*> edgesAtVertex; edgesAtVertex.SetCount(v.Count()); for (int i = 0; i < v.Count(); i++) edgesAtVertex[i] = NULL; for (int i = 0; i < ePtrList.Count(); i++) { int a = ePtrList[i]->a; if (pointSel[a]) { if (edgesAtVertex[a] == NULL) edgesAtVertex[a] = new VEdges(); edgesAtVertex[a]->edgeIndex.Append(1,&i,5); } a = ePtrList[i]->b; if (pointSel[a]) { if (edgesAtVertex[a] == NULL) edgesAtVertex[a] = new VEdges(); edgesAtVertex[a]->edgeIndex.Append(1,&i,5); } } BitArray processedFaces; processedFaces.SetSize(f.Count()); BitArray processedEdges; processedEdges.SetSize(ePtrList.Count()); int originalCount = v.Count(); for (int i = 0; i < originalCount; i++) { if (pointSel[i]) { processedFaces.ClearAll(); processedEdges.ClearAll(); int ct = edgesAtVertex[i]->edgeIndex.Count(); BOOL first = TRUE; for (int j = 0; j < ct; j++) { int currrentEdgeIndex = edgesAtVertex[i]->edgeIndex[j]; //find a selected edge if (esel[currrentEdgeIndex]) { int numFaces = ePtrList[currrentEdgeIndex]->faceList.Count(); for (int m = 0; m < numFaces; m++) { int newVertIndex = -1; if (first) { //just set the index newVertIndex = i; first = FALSE; } else { //create a new vertex UVW_TVVertClass newVert; newVert.SetP(v[i].GetP()); newVert.SetInfluence(0.0f); newVert.SetFlag(0); //create a new handle if we need one v.Append(1,&newVert); newVertIndex = v.Count()-1; } int currentFaceIndex = ePtrList[currrentEdgeIndex]->faceList[m]; if (!processedFaces[currentFaceIndex]) { BOOL done = FALSE; int lastEdge = j; while (!done) { //loop through this face looking for matching vert int deg = f[currentFaceIndex]->count; for (int n = 0; n < deg; n++) { //replace it if (f[currentFaceIndex]->t[n] == i) { f[currentFaceIndex]->t[n] = newVertIndex; } } processedFaces.Set(currentFaceIndex,TRUE); //loop til we find another selected face or an opent edge int nextEdge = -1; for (int n = 0; n < ct; n++) { //mkae sure we are not looking at the current edge int potentialEdge = edgesAtVertex[i]->edgeIndex[n]; if (n != lastEdge) { int nfaces = ePtrList[potentialEdge]->faceList.Count(); if (nfaces != -1) { for (int p = 0; p < nfaces; p++) { if (ePtrList[potentialEdge]->faceList[p] == currentFaceIndex) { nextEdge = potentialEdge; lastEdge = n; p = nfaces; n = ct; } } } } } //if we hit an edge we are done with this cluster if (nextEdge==-1) done = TRUE; else if (ePtrList[nextEdge]->a == ePtrList[nextEdge]->b) done = TRUE; else if (esel[nextEdge]) done = TRUE; else if (nextEdge != -1) { //get the next face int nfaces = ePtrList[nextEdge]->faceList.Count(); BOOL hit = FALSE; for (int p = 0; p < nfaces; p++) { if (ePtrList[nextEdge]->faceList[p]!= currentFaceIndex) { currentFaceIndex = ePtrList[nextEdge]->faceList[p]; hit = TRUE; p = nfaces; } } if (!hit) done = TRUE; } } } } } } } } for (int i = 0; i < originalCount; i++) { if (edgesAtVertex[i]) delete edgesAtVertex[i]; } BuildEdges(); BuildGeomEdges(); Tab<int> numberConnectedEdges; numberConnectedEdges.SetCount(v.Count()); for (int i = 0; i < v.Count(); i++) { numberConnectedEdges[i] = 0; } //loop through our egdes for (int i = 0; i < ePtrList.Count(); i++) { int veca = ePtrList[i]->avec; int vecb = ePtrList[i]->bvec; if (veca != -1) numberConnectedEdges[veca] += 1; if (vecb != -1) numberConnectedEdges[vecb] += 1; } for (int i = 0; i < f.Count(); i++) { if (f[i]->vecs) { int deg = f[i]->count; for (int j = 0; j < deg*2; j++) { int va; va = f[i]->vecs->handles[j]; if (numberConnectedEdges[va] > 1) { //clone the vert UVW_TVVertClass newVert; newVert.SetP(v[va].GetP()); newVert.SetInfluence(0.0f); newVert.SetFlag(0); //create a new handle if we need one v.Append(1,&newVert); int newVertIndex = v.Count()-1; //assign it f[i]->vecs->handles[j] = newVertIndex; //dec our counrt numberConnectedEdges[va] -= 1; } } } } mSystemLockedFlag.SetSize(v.Count(), 1); BuildEdges(); BuildGeomEdges(); }
void StencilShadow::RenderShadow() { #ifndef DISABLE_STENCILSHADOW DWORD lighting, fog, srcblend, destblend, alphablend, zwrite, zfunc, cullmode; GL_State(GLS_DEFAULT); glw_state->device->GetRenderState( D3DRS_LIGHTING, &lighting ); glw_state->device->GetRenderState( D3DRS_FOGENABLE, &fog ); glw_state->device->GetRenderState( D3DRS_SRCBLEND, &srcblend ); glw_state->device->GetRenderState( D3DRS_DESTBLEND, &destblend ); glw_state->device->GetRenderState( D3DRS_ALPHABLENDENABLE, &alphablend ); glw_state->device->GetRenderState( D3DRS_ZWRITEENABLE, &zwrite ); glw_state->device->GetRenderState( D3DRS_ZFUNC, &zfunc ); glw_state->device->GetRenderState( D3DRS_CULLMODE, &cullmode ); pVerts = NULL; pExtrusions = NULL; GL_Bind( tr.whiteImage ); glw_state->device->SetRenderState( D3DRS_LIGHTING, FALSE ); glw_state->device->SetRenderState( D3DRS_FOGENABLE, FALSE ); glw_state->device->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE ); glw_state->device->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO ); // Disable z-buffer writes (note: z-testing still occurs), and enable the // stencil-buffer glw_state->device->SetRenderState( D3DRS_ZWRITEENABLE, FALSE ); glw_state->device->SetRenderState( D3DRS_STENCILENABLE, TRUE ); // Don't bother with interpolating color glw_state->device->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT ); glw_state->device->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESS ); // Set up stencil compare function, reference value, and masks. // Stencil test passes if ((ref & mask) cmpfn (stencil & mask)) is true. // Note: since we set up the stencil-test to always pass, the STENCILFAIL // renderstate is really not needed. glw_state->device->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS ); #ifdef _STENCIL_REVERSE glw_state->device->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR ); glw_state->device->SetRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP ); glw_state->device->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP ); #else glw_state->device->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP ); glw_state->device->SetRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP ); glw_state->device->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_INCR ); #endif // If ztest passes, inc/decrement stencil buffer value glw_state->device->SetRenderState( D3DRS_STENCILREF, 0x1 ); glw_state->device->SetRenderState( D3DRS_STENCILMASK, 0x7f ); //0xffffffff ); glw_state->device->SetRenderState( D3DRS_STENCILWRITEMASK, 0x7f ); //0xffffffff ); // Make sure that no pixels get drawn to the frame buffer glw_state->device->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); glw_state->device->SetRenderState( D3DRS_COLORWRITEENABLE, 0 ); glw_state->device->SetTexture(0, NULL); glw_state->device->SetTexture(1, NULL); // Compute the matrix set XGMATRIX matComposite, matProjectionViewport, matWorld; glw_state->device->GetProjectionViewportMatrix( &matProjectionViewport ); XGMatrixMultiply( &matComposite, (XGMATRIX*)glw_state->matrixStack[glwstate_t::MatrixMode_Model]->GetTop(), &matProjectionViewport ); // Transpose and set the composite matrix. XGMatrixTranspose( &matComposite, &matComposite ); glw_state->device->SetVertexShaderConstant( CV_WORLDVIEWPROJ_0, &matComposite, 4 ); // Set viewport offsets. float fViewportOffsets[4] = { 0.53125f, 0.53125f, 0.0f, 0.0f }; glw_state->device->SetVertexShaderConstant( CV_VIEWPORT_OFFSETS, &fViewportOffsets, 1 ); glw_state->device->SetVertexShader(m_dwVertexShaderShadow); #ifdef _STENCIL_REVERSE qglCullFace( GL_FRONT ); #else qglCullFace( GL_BACK ); #endif BuildEdges(); // Draw front-side of shadow volume in stencil/z only if(m_nIndexes) renderObject_Shadow( D3DPT_QUADLIST, m_nIndexes, m_shadowIndexes ); #ifdef _STENCIL_REVERSE if(m_nIndexesCap) renderObject_Shadow( D3DPT_TRIANGLELIST, m_nIndexesCap, m_shadowIndexesCap ); #endif // Now reverse cull order so back sides of shadow volume are written. #ifdef _STENCIL_REVERSE qglCullFace( GL_BACK ); #else qglCullFace( GL_FRONT ); #endif // Decrement stencil buffer value #ifdef _STENCIL_REVERSE glw_state->device->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR ); #else glw_state->device->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_DECR ); #endif // Draw back-side of shadow volume in stencil/z only if(m_nIndexes) renderObject_Shadow( D3DPT_QUADLIST, m_nIndexes, m_shadowIndexes ); #ifdef _STENCIL_REVERSE if(m_nIndexesCap) renderObject_Shadow( D3DPT_TRIANGLELIST, m_nIndexesCap, m_shadowIndexesCap ); #endif // Restore render states glw_state->device->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALL ); glw_state->device->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD ); glw_state->device->SetRenderState( D3DRS_STENCILENABLE, FALSE ); glw_state->device->SetRenderState( D3DRS_LIGHTING, lighting ); glw_state->device->SetRenderState( D3DRS_FOGENABLE, fog ); glw_state->device->SetRenderState( D3DRS_SRCBLEND, srcblend ); glw_state->device->SetRenderState( D3DRS_DESTBLEND, destblend ); glw_state->device->SetRenderState( D3DRS_ALPHABLENDENABLE, alphablend ); glw_state->device->SetRenderState( D3DRS_ZWRITEENABLE, zwrite ); glw_state->device->SetRenderState( D3DRS_ZFUNC, zfunc ); glw_state->device->SetRenderState( D3DRS_CULLMODE, cullmode ); #endif }