summaryrefslogtreecommitdiff
path: root/game/client/portal/Portal_DynamicMeshRenderingUtils.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/portal/Portal_DynamicMeshRenderingUtils.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/client/portal/Portal_DynamicMeshRenderingUtils.cpp')
-rw-r--r--game/client/portal/Portal_DynamicMeshRenderingUtils.cpp183
1 files changed, 183 insertions, 0 deletions
diff --git a/game/client/portal/Portal_DynamicMeshRenderingUtils.cpp b/game/client/portal/Portal_DynamicMeshRenderingUtils.cpp
new file mode 100644
index 0000000..f5b32fa
--- /dev/null
+++ b/game/client/portal/Portal_DynamicMeshRenderingUtils.cpp
@@ -0,0 +1,183 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "Portal_DynamicMeshRenderingUtils.h"
+#include "iviewrender.h"
+
+extern ConVar mat_wireframe;
+
+
+int ClipPolyToPlane_LerpTexCoords( PortalMeshPoint_t *inVerts, int vertCount, PortalMeshPoint_t *outVerts, const Vector& normal, float dist, float fOnPlaneEpsilon )
+{
+ vec_t *dists = (vec_t *)stackalloc( sizeof(vec_t) * vertCount * 4 ); //4x vertcount should cover all cases
+ int *sides = (int *)stackalloc( sizeof(int) * vertCount * 4 );
+ int counts[3];
+ vec_t dot;
+ int i, j;
+ Vector mid = vec3_origin;
+ int outCount;
+
+ counts[0] = counts[1] = counts[2] = 0;
+
+ // determine sides for each point
+ for ( i = 0; i < vertCount; i++ )
+ {
+ dot = DotProduct( inVerts[i].vWorldSpacePosition, normal) - dist;
+ dists[i] = dot;
+ if ( dot > fOnPlaneEpsilon )
+ sides[i] = SIDE_FRONT;
+ else if ( dot < -fOnPlaneEpsilon )
+ sides[i] = SIDE_BACK;
+ else
+ sides[i] = SIDE_ON;
+ counts[sides[i]]++;
+ }
+ sides[i] = sides[0];
+ dists[i] = dists[0];
+
+ if (!counts[0])
+ return 0;
+
+ if (!counts[1])
+ {
+ // Copy to output verts
+ //for ( i = 0; i < vertCount; i++ )
+ memcpy( outVerts, inVerts, sizeof( PortalMeshPoint_t ) * vertCount );
+ return vertCount;
+ }
+
+ outCount = 0;
+ for ( i = 0; i < vertCount; i++ )
+ {
+ if (sides[i] == SIDE_ON)
+ {
+ memcpy( &outVerts[outCount], &inVerts[i], sizeof( PortalMeshPoint_t ) );
+ ++outCount;
+ continue;
+ }
+ if (sides[i] == SIDE_FRONT)
+ {
+ memcpy( &outVerts[outCount], &inVerts[i], sizeof( PortalMeshPoint_t ) );
+ ++outCount;
+ }
+ if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
+ continue;
+
+ Vector& p1 = inVerts[i].vWorldSpacePosition;
+
+
+ // generate a split point
+ int i2 = (i+1)%vertCount;
+ Vector& p2 = inVerts[i2].vWorldSpacePosition;
+
+ dot = dists[i] / (dists[i]-dists[i+1]);
+ for (j=0 ; j<3 ; j++)
+ {
+ mid[j] = p1[j] + dot*(p2[j]-p1[j]);
+ }
+
+ VectorCopy (mid, outVerts[outCount].vWorldSpacePosition);
+
+ outVerts[outCount].texCoord.x = inVerts[i].texCoord.x + dot*(inVerts[i2].texCoord.x - inVerts[i].texCoord.x);
+ outVerts[outCount].texCoord.y = inVerts[i].texCoord.y + dot*(inVerts[i2].texCoord.y - inVerts[i].texCoord.y);
+
+ ++outCount;
+ }
+
+ return outCount;
+}
+
+void RenderPortalMeshConvexPolygon( PortalMeshPoint_t *pVerts, int iVertCount, const IMaterial *pMaterial, void *pBind )
+{
+ CMatRenderContextPtr pRenderContext( materials );
+ pRenderContext->Bind( (IMaterial *)pMaterial, pBind );
+
+ //PortalMeshPoint_t *pMidVerts = (PortalMeshPoint_t *)stackalloc( sizeof( PortalMeshPoint_t ) * iVertCount );
+
+ CMeshBuilder meshBuilder;
+ IMesh* pMesh = pRenderContext->GetDynamicMesh( true );
+ meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, iVertCount - 2 );
+
+ //any convex polygon can be rendered with a triangle strip by starting at a vertex and alternating vertices from each side
+ int iForwardCounter = 0;
+ int iReverseCounter = iVertCount - 1; //guaranteed to be >= 2 to start
+
+ do
+ {
+ PortalMeshPoint_t *pVertex = &pVerts[iForwardCounter];
+ meshBuilder.Position3fv( &pVertex->vWorldSpacePosition.x );
+ meshBuilder.TexCoord2fv( 0, &pVertex->texCoord.x );
+ meshBuilder.AdvanceVertex();
+ ++iForwardCounter;
+
+ if( iForwardCounter > iReverseCounter )
+ break;
+
+ pVertex = &pVerts[iReverseCounter];
+ meshBuilder.Position3fv( &pVertex->vWorldSpacePosition.x );
+ meshBuilder.TexCoord2fv( 0, &pVertex->texCoord.x );
+ meshBuilder.AdvanceVertex();
+ --iReverseCounter;
+ } while( iForwardCounter <= iReverseCounter );
+
+ meshBuilder.End();
+ pMesh->Draw();
+}
+
+
+void Clip_And_Render_Convex_Polygon( PortalMeshPoint_t *pVerts, int iVertCount, const IMaterial *pMaterial, void *pBind )
+{
+ PortalMeshPoint_t *pInVerts = (PortalMeshPoint_t *)stackalloc( iVertCount * 4 * sizeof( PortalMeshPoint_t ) ); //really only should need 2x points, but I'm paranoid
+ PortalMeshPoint_t *pOutVerts = (PortalMeshPoint_t *)stackalloc( iVertCount * 4 * sizeof( PortalMeshPoint_t ) );
+ PortalMeshPoint_t *pTempVerts;
+
+
+ //clip by the viewing frustum
+ {
+ VPlane *pFrustum = view->GetFrustum();
+
+ //clip by first plane and put output into pInVerts
+ iVertCount = ClipPolyToPlane_LerpTexCoords( pVerts, iVertCount, pInVerts, pFrustum[0].m_Normal, pFrustum[0].m_Dist, 0.01f );
+
+ //clip by other planes and flipflop in and out pointers
+ for( int i = 1; i != FRUSTUM_NUMPLANES; ++i )
+ {
+ if( iVertCount < 3 )
+ return; //nothing to draw
+
+ iVertCount = ClipPolyToPlane_LerpTexCoords( pInVerts, iVertCount, pOutVerts, pFrustum[i].m_Normal, pFrustum[i].m_Dist, 0.01f );
+ pTempVerts = pInVerts; pInVerts = pOutVerts; pOutVerts = pTempVerts; //swap vertex pointers
+ }
+
+ if( iVertCount < 3 )
+ return; //nothing to draw
+ }
+
+ CMatRenderContextPtr pRenderContext( materials );
+
+ RenderPortalMeshConvexPolygon( pOutVerts, iVertCount, pMaterial, pBind );
+ if( mat_wireframe.GetBool() )
+ RenderPortalMeshConvexPolygon( pOutVerts, iVertCount, materials->FindMaterial( "shadertest/wireframe", TEXTURE_GROUP_CLIENT_EFFECTS, false ), pBind );
+
+ stackfree( pOutVerts );
+ stackfree( pInVerts );
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+