.:: Bots United ::.

.:: Bots United ::. (http://forums.bots-united.com/index.php)
-   Half-Life 1 SDK (http://forums.bots-united.com/forumdisplay.php?f=33)
-   -   Lightmap performance drop (http://forums.bots-united.com/showthread.php?t=3485)

Lazy 26-01-2005 20:47

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


Pierre-Marie Baty 26-01-2005 22:06

Re: Lightmap performance drop
 
ouch... client code.
I know nothing about client-side code :(

anyway, that code itself shouldn't make the client slow down... I suppose these are one-time call functions ? Make sure you're not calling DisableLightmaps() each frame, that would rather sound like it to me...

Lazy 26-01-2005 22:10

Re: Lightmap performance drop
 
Nah, DisableLightmaps is being called once only.
I'm trying to get this on the HL2SDK but I can't find the model_t definition!
Its driving me up the wall!

Thats the good thing about the hl1 sdk, soo much more organized lol. I guess I just have to get used to it :/

I'm still bothered by the slowdown though, it does the same thing when r_fullbright is set to 1 so my code ( should ) be fine.

@$3.1415rin 27-01-2005 17:17

Re: Lightmap performance drop
 
I guess that's really because you already know that old code for years.

really strange, since that would save one texture stage. maybe there's just something strange inside the HL engine, which hasnt been touched for years, since nobody used it and thus it's unoptimized.

and btw : // TODO:
// Unroll this loop...


i'd suggest you don't care about that and let the compiler decide :)

Lazy 27-01-2005 17:44

Re: Lightmap performance drop
 
Hehe, if only I had an optimizing compiler :)
I still think its a better idea to hand optimize things since you can see things the compiler can't.

[Quick rant]
BAH! There is no model_t definition, its just used as a pointer so the engine can give you various bits of information from a model.
That really sucks since this lightmap method of illuminating the world cannot work now.

sfx1999 27-01-2005 17:59

Re: Lightmap performance drop
 
Maybe it has to do with disabling and reenabling multitexturing.

Lazy 27-01-2005 18:02

Re: Lightmap performance drop
 
I was thinking that might have something to do with it but I do not know enough about OpenGL to re-enable it ( If it's even possible without the engine code ).

sfx1999 27-01-2005 18:12

Re: Lightmap performance drop
 
Even so, it would still be disabling and renabling.

Anyway, that probably isn't it, because the HUD doesn't cause a slowdown like that.

Lazy 29-01-2005 20:56

Re: Lightmap performance drop
 
Slightly off topic:
===============

I'm trying some things to prevent certain commands from being used, the only problem is that some are handled completely by the engine and cannot be blocked or changed.

I found this in the QuakeWorld client source...
Code:

typedef struct cmd_function_s
{
        struct cmd_function_s        *next;
        char                                        *name;
        xcommand_t                                function;
} cmd_function_t;

...
...
...
...

static        cmd_function_t    *cmd_functions;                // possible commands to execute

Since both engines are similar I hope that structure hasn't changed so that the functions can be hooked after they are received by the network socket.

The question is how do I find it in memory?
If I were to get some memory reading tool I could look for "rate" or something and find the start of the command list by working backwards.

Can you reccommend any memory searching tools?
I looked for memory dumping programs but only found pages relating to the windows blue screen physical memory dump.

Pierre-Marie Baty 30-01-2005 02:02

Re: Lightmap performance drop
 
The only memory search tool I can recommand is TSearch, because it's the only one I know (and I wouldn't be surprised if it was the only one existing). It was originally a tool to search for cheats for console games running in emulators (like in UltraHLE, I believe the Zelda cheats were discovered with that tool).

More on topic, I know nothing like the code you posted in the HL engine... I was thinking that all client commands were going either through client commands or impulses, or through usercmd_t's.


All times are GMT +2. The time now is 05:39.

Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.