View Single Post
Lightmap performance drop
Old
  (#1)
Lazy
Member
 
Lazy's Avatar
 
Status: Offline
Posts: 236
Join Date: Jan 2004
Location: Toronto, Ontario, Canada
Default Lightmap performance drop - 26-01-2005

This has been bugging the hell out of me, for some reason the Half-Life engine chokes when there are no lightmaps to be drawn.
I had an idea for nightvision that wouldn't have to rely on dynamic lights but disable the lightmaps which would make the world fullbright and then I could draw over the screen for the nv effect.
I'm able to disable the lightmaps fine but the engine takes a very noticable performance hit of anywhere between 10-30fps, I thought the engine would have LESS to do...
And after the world has been made fullbright it won't go back, even after the surfaces have been restored the world stays the same.

Any ideas why this is happening?

Note: Thrown together code
Code:
#include <windows.h>
#include "hud.h"
#include "cl_util.h"

#include <vector>

#define HARDWARE_MODE
#include "com_model.h"

typedef struct {
   int cached_light[ MAXLIGHTMAPS ];
   int msurface_index;
}
lightdatasave_t;

std::vector< lightdatasave_t >g_vSavedlights;
void* g_pLightdata = NULL;

void DisableLightmaps( void ) {
   cl_entity_t*   pWorldspawn	= NULL;
   model_t*	   pWorld		 = NULL;
   DWORD		  dwOldprotect   = 0;
   register int   i			  = 0;
   register int   lm			 = 0;
   lightdatasave_t lSaved;

   // Clear out the saved lights vector
   g_vSavedlights.clear( );

   // Get a pointer to the worldspawn entity
   pWorldspawn = gEngfuncs.GetEntityByIndex( 0 );

   // Return on failure
   if ( ! pWorldspawn )
	  return;

   // Get the world model
   pWorld = pWorldspawn->model;

   // Return if we don't have a valid pointer for the model, marksurfaces or
   // lightmap data.
   if ( ! pWorld || ! pWorld->marksurfaces || ! pWorld->lightdata )
	  return;

   // Allow writes to the lightdata pointer
   VirtualProtect( ( ( void* ) &pWorld->lightdata ), sizeof( void* ), PAGE_READWRITE, &dwOldprotect );

   // Save the lightdata pointer, then disable it.
   g_pLightdata = ( void* ) pWorld->lightdata;
   pWorld->lightdata = NULL;

   // Restore the protection on the lightmap data
   VirtualProtect( ( ( void* ) &pWorld->lightdata ), sizeof( void* ), dwOldprotect, &dwOldprotect );

   // Allow writes to the marksurfaces
 VirtualProtect( ( void* ) pWorld->marksurfaces, pWorld->nummarksurfaces * sizeof( msurface_t ), PAGE_READWRITE, &dwOldprotect );

   // Loop through all of the marksurfaces and kill their lightmap
   // data
   for ( ; i < pWorld->nummarksurfaces; i++ ) {
	  // Copy the cached_light member from the surface and the surface index into
	  // our temporary structure.
	 memcpy( lSaved.cached_light, pWorld->marksurfaces[ i ]->cached_light, sizeof( int ) * MAXLIGHTMAPS );
	  lSaved.msurface_index = i;

	  // Add it to the vector
	  g_vSavedlights.push_back( lSaved );

	  // TODO:
	  // Unroll this loop...
	  for ( lm = 0; lm < MAXLIGHTMAPS; lm++ ) {
		 // Fullbright!
		 pWorld->marksurfaces[ i ]->cached_light[ lm ] = 255;
	  }
   }

   // Restore protection to the marksurfaces
 VirtualProtect( ( void* ) pWorld->marksurfaces, pWorld->nummarksurfaces * sizeof( msurface_t ), dwOldprotect, &dwOldprotect );
}

void RestoreLightmaps( void ) {
   cl_entity_t*   pWorldspawn	= NULL;
   model_t*	   pWorld		 = NULL;
   DWORD		  dwOldprotect   = 0;
   register int   i			  = 0;
   register int   lm			 = 0;
   lightdatasave_t* ptr		  = NULL;
   std::vector< lightdatasave_t >::iterator iBegin;
   std::vector< lightdatasave_t >::iterator iEnd;

   iBegin = g_vSavedlights.begin( );
   iEnd = g_vSavedlights.end( );

   // Get a pointer to the worldspawn entity
   pWorldspawn = gEngfuncs.GetEntityByIndex( 0 );

   // Return on failure
   if ( ! pWorldspawn )
	  return;

   // Get the world model
   pWorld = pWorldspawn->model;

   // Return if we don't have a valid pointer for the model, marksurfaces or
   // lightmap data.
   if ( ! pWorld || ! pWorld->marksurfaces || ! pWorld->lightdata )
	  return;

   // Allow writes to the lightdata pointer
   VirtualProtect( ( ( void* ) &pWorld->lightdata ), sizeof( void* ), PAGE_READWRITE, &dwOldprotect );

   // Restore the model's lightmap data pointer
   pWorld->lightdata = ( color24* ) g_pLightdata;
   g_pLightdata = NULL;

   // Restore the protection on the lightmap data
   VirtualProtect( ( ( void* ) &pWorld->lightdata ), sizeof( void* ), dwOldprotect, &dwOldprotect );

   // Allow writes to the marksurfaces
 VirtualProtect( ( void* ) pWorld->marksurfaces, pWorld->nummarksurfaces * sizeof( msurface_t ), PAGE_READWRITE, &dwOldprotect );

   while ( iBegin != iEnd ) {
	  ptr = ( lightdatasave_t* ) &( *iBegin );

	  if ( ptr )
		 memcpy( pWorld->marksurfaces[ ptr->msurface_index ]->cached_light, ptr->cached_light, sizeof( int ) * MAXLIGHTMAPS );

	  iBegin++;
   }

   // Restore protection to the marksurfaces
 VirtualProtect( ( void* ) pWorld->marksurfaces, pWorld->nummarksurfaces * sizeof( msurface_t ), dwOldprotect, &dwOldprotect );

   // Clear out the saved data vector
   g_vSavedlights.clear( );
}
  
Reply With Quote