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( );
}