@@ -27,6 +27,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2727
2828#include " GeometryOptimiser.h"
2929
30+ #include " ShadeCommon.h"
31+
3032static int LeafSurfaceCompare ( const void * a, const void * b ) {
3133 bspSurface_t* aa, * bb;
3234
@@ -419,33 +421,10 @@ void MergeDuplicateVertices( bspSurface_t** rendererSurfaces, int numSurfaces, s
419421 Log::Notice ( " Merged %i vertices into %i in %i ms" , numVerticesIn, numVerticesOut, Sys::Milliseconds () - start );
420422}
421423
422- /* static void ProcessMaterialSurface( MaterialSurface& surface, std::vector<MaterialSurface>& materialSurfaces,
423- std::vector<MaterialSurface>& processedMaterialSurfaces,
424- srfVert_t* verts, glIndex_t* indices ) {
425- if ( surface.count == MAX_MATERIAL_SURFACE_TRIS ) {
426- materialSurfaces.emplace_back( surface );
427- }
428-
429- while ( surface.count > MAX_MATERIAL_SURFACE_TRIS ) {
430- MaterialSurface srf = surface;
431-
432- srf.count = MAX_MATERIAL_SURFACE_TRIS;
433- surface.count -= MAX_MATERIAL_SURFACE_TRIS;
434- surface.firstIndex += MAX_MATERIAL_SURFACE_TRIS;
435-
436- processedMaterialSurfaces.push_back( srf );
437- }
438- } */
439-
440424std::vector<MaterialSurface> OptimiseMapGeometryMaterial (bspSurface_t** rendererSurfaces, int numSurfaces ) {
441425 std::vector<MaterialSurface> materialSurfaces;
442426 materialSurfaces.reserve ( numSurfaces );
443427
444- std::vector<MaterialSurface> processedMaterialSurfaces;
445- processedMaterialSurfaces.reserve ( numSurfaces );
446-
447- // std::unordered_map<TriEdge, TriIndex> triEdges;
448-
449428 vec3_t worldBounds[2 ] = {};
450429 materialSystem.buildOneShader = false ;
451430 for ( int i = 0 ; i < numSurfaces; i++ ) {
@@ -482,13 +461,128 @@ std::vector<MaterialSurface> OptimiseMapGeometryMaterial(bspSurface_t** renderer
482461
483462 materialSurfaces.emplace_back ( srf );
484463 }
485-
486464 materialSystem.buildOneShader = true ;
487465
466+ /* GenerateWorldMaterialsBuffer() must be called before the surface merging loop, because it will compare the UBO offsets,
467+ which are set by this call */
488468 materialSystem.GenerateWorldMaterialsBuffer ();
469+
470+ std::vector<MaterialSurface> processedMaterialSurfaces;
471+ processedMaterialSurfaces.reserve ( numSurfaces );
472+ for ( uint32_t i = 0 ; i < materialSurfaces.size (); i++ ) {
473+ MaterialSurface* surface = &materialSurfaces[i];
474+
475+ if ( surface->merged ) {
476+ continue ;
477+ }
478+
479+ uint32_t lastIndex = surface->firstIndex + surface->count ;
480+ for ( uint32_t j = i + 1 ; j < materialSurfaces.size (); j++ ) {
481+ MaterialSurface* surface2 = &materialSurfaces[j];
482+
483+ if ( surface2->merged ) {
484+ continue ;
485+ }
486+
487+ if ( surface->stages != surface2->stages ) {
488+ continue ;
489+ }
490+
491+ if ( surface->count + surface2->count > MAX_MATERIAL_SURFACE_INDEXES ) {
492+ continue ;
493+ }
494+
495+ vec3_t mins;
496+ vec3_t maxs;
497+ ClearBounds ( mins, maxs );
498+ for ( uint32_t k = 0 ; k < surface->count ; k++ ) {
499+ AddPointToBounds ( vertices[idxs[k + surface->firstIndex ]].xyz , mins, maxs );
500+ }
501+
502+ for ( uint32_t k = 0 ; k < surface2->count ; k++ ) {
503+ AddPointToBounds ( vertices[indices[k + surface2->firstIndex ]].xyz , mins, maxs );
504+ }
505+
506+ vec3_t origin;
507+ float radius;
508+ SphereFromBounds ( mins, maxs, origin, &radius );
509+
510+ // Check both against a mul and add increase, so we can reasonably merge both large and small surfaces
511+ if ( radius > surface->radius * MAX_MATERIAL_SURFACE_RADIUS_INCREASE
512+ && radius > surface->radius + MAX_MATERIAL_SURFACE_RADIUS_INCREASE_ADD ) {
513+ continue ;
514+ }
515+
516+ bool skip = false ;
517+ for ( uint8_t stage = 0 ; stage < surface->stages ; stage++ ) {
518+ if ( ( surface->materialPackIDs [stage] != surface2->materialPackIDs [stage] )
519+ || ( surface->materialIDs [stage] != surface2->materialIDs [stage] ) ) {
520+ skip = true ;
521+ break ;
522+ }
523+
524+ shaderStage_t* pStage = surface->shaderStages [stage];
525+ pStage = pStage->materialRemappedStage ? pStage->materialRemappedStage : pStage;
526+
527+ const uint32_t surfaceMaterialID =
528+ pStage->materialOffset + pStage->variantOffsets [surface->shaderVariant [stage]];
529+
530+ pStage = surface2->shaderStages [stage];
531+ pStage = pStage->materialRemappedStage ? pStage->materialRemappedStage : pStage;
532+
533+ const uint32_t surfaceMaterialID2 =
534+ pStage->materialOffset + pStage->variantOffsets [surface2->shaderVariant [stage]];
535+
536+ if ( surfaceMaterialID != surfaceMaterialID2 ) {
537+ skip = true ;
538+ break ;
539+ }
540+
541+ uint32_t texData = surface->texDataDynamic [stage]
542+ ? ( surface->texDataIDs [stage] + materialSystem.GetTexDataSize () ) << TEX_BUNDLE_BITS
543+ : surface->texDataIDs [stage] << TEX_BUNDLE_BITS ;
544+ texData |= ( HasLightMap ( surface ) ? GetLightMapNum ( surface ) : 255 ) << LIGHTMAP_BITS ;
545+
546+ uint32_t texData2 = surface2->texDataDynamic [stage]
547+ ? ( surface2->texDataIDs [stage] + materialSystem.GetTexDataSize () ) << TEX_BUNDLE_BITS
548+ : surface2->texDataIDs [stage] << TEX_BUNDLE_BITS ;
549+ texData2 |= ( HasLightMap ( surface2 ) ? GetLightMapNum ( surface2 ) : 255 ) << LIGHTMAP_BITS ;
550+
551+ if ( texData != texData2 ) {
552+ skip = true ;
553+ break ;
554+ }
555+ }
556+
557+ if ( skip ) {
558+ continue ;
559+ }
560+
561+ if ( surface2->firstIndex == lastIndex ) {
562+ surface->count += surface2->count ;
563+ lastIndex += surface2->count ;
564+
565+ VectorCopy ( origin, surface->origin );
566+ surface->radius = radius;
567+
568+ surface2->merged = true ;
569+ }
570+
571+ if ( surface->count >= MAX_MATERIAL_SURFACE_INDEXES ) {
572+ break ;
573+ }
574+ }
575+ }
576+
577+ for ( MaterialSurface& srf : materialSurfaces ) {
578+ if ( !srf.merged ) {
579+ processedMaterialSurfaces.push_back ( srf );
580+ }
581+ }
582+
489583 materialSystem.GeneratePortalBoundingSpheres ();
490584 materialSystem.SetWorldBounds ( worldBounds );
491- materialSystem.GenerateWorldCommandBuffer ( materialSurfaces );
585+ materialSystem.GenerateWorldCommandBuffer ( processedMaterialSurfaces );
492586
493587 return materialSurfaces;
494588}
0 commit comments