Added per-thing render hooks

This commit is contained in:
ZZYZX 2017-01-22 07:04:35 +02:00
parent 841c7c9712
commit 9c1c7129c1
5 changed files with 97 additions and 20 deletions

View File

@ -53,6 +53,18 @@ void E_RenderCamera()
handler->RenderCamera();
}
void E_RenderBeforeThing(AActor* thing)
{
for (DEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next)
handler->RenderBeforeThing(thing);
}
void E_RenderAfterThing(AActor* thing)
{
for (DEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next)
handler->RenderAfterThing(thing);
}
// declarations
IMPLEMENT_CLASS(DEventHandler, false, false);
IMPLEMENT_CLASS(DRenderEventHandler, false, false);
@ -62,6 +74,8 @@ DEFINE_FIELD_X(RenderEventHandler, DRenderEventHandler, ViewAngle);
DEFINE_FIELD_X(RenderEventHandler, DRenderEventHandler, ViewPitch);
DEFINE_FIELD_X(RenderEventHandler, DRenderEventHandler, ViewRoll);
DEFINE_FIELD_X(RenderEventHandler, DRenderEventHandler, FracTic);
DEFINE_FIELD_X(RenderEventHandler, DRenderEventHandler, Camera);
DEFINE_FIELD_X(RenderEventHandler, DRenderEventHandler, CurrentThing);
DEFINE_ACTION_FUNCTION(DEventHandler, Create)
{
@ -109,12 +123,12 @@ DEFINE_ACTION_FUNCTION(DEventHandler, Unregister)
return 0;
}
#define DEFINE_EVENT_HANDLER(cls, funcname) DEFINE_ACTION_FUNCTION(cls, funcname) \
#define DEFINE_EVENT_HANDLER(cls, funcname, args) DEFINE_ACTION_FUNCTION(cls, funcname) \
{ \
PARAM_SELF_PROLOGUE(cls); \
return 0; \
} \
void cls::funcname() \
void cls::funcname(args) \
{ \
IFVIRTUAL(cls, funcname) \
{ \
@ -125,10 +139,12 @@ void cls::funcname() \
} \
}
DEFINE_EVENT_HANDLER(DEventHandler, MapLoaded)
DEFINE_EVENT_HANDLER(DEventHandler, MapUnloading)
DEFINE_EVENT_HANDLER(DEventHandler, RenderFrame)
DEFINE_EVENT_HANDLER(DEventHandler, RenderCamera)
DEFINE_EVENT_HANDLER(DEventHandler, MapLoaded,)
DEFINE_EVENT_HANDLER(DEventHandler, MapUnloading,)
DEFINE_EVENT_HANDLER(DEventHandler, RenderFrame,)
DEFINE_EVENT_HANDLER(DEventHandler, RenderCamera,)
DEFINE_EVENT_HANDLER(DEventHandler, RenderBeforeThing, AActor*)
DEFINE_EVENT_HANDLER(DEventHandler, RenderAfterThing, AActor*)
//
void DEventHandler::OnDestroy()
@ -144,6 +160,7 @@ void DRenderEventHandler::Setup()
ViewPitch = ::ViewPitch;
ViewRoll = ::ViewRoll;
FracTic = ::r_TicFracF;
Camera = ::camera;
}
void DRenderEventHandler::RenderFrame()
@ -157,3 +174,15 @@ void DRenderEventHandler::RenderCamera()
Setup();
DEventHandler::RenderCamera();
}
void DRenderEventHandler::RenderBeforeThing(AActor* thing)
{
CurrentThing = thing;
DEventHandler::RenderBeforeThing(thing);
}
void DRenderEventHandler::RenderAfterThing(AActor* thing)
{
CurrentThing = thing;
DEventHandler::RenderAfterThing(thing);
}

View File

@ -3,6 +3,26 @@
#include "dobject.h"
class DEventHandler;
// register
void E_RegisterHandler(DEventHandler* handler);
// unregister
void E_UnregisterHandler(DEventHandler* handler);
// called right after the map has loaded (approximately same time as OPEN ACS scripts)
void E_MapLoaded();
// called when the map is about to unload (approximately same time as UNLOADING ACS scripts)
void E_MapUnloading();
// called on each render frame once.
void E_RenderFrame();
// called before entering each actor's view (including RenderFrame)
void E_RenderCamera();
// called before adding each actor to the render list
void E_RenderBeforeThing(AActor* thing);
// called after adding each actor to the render list
void E_RenderAfterThing(AActor* thing);
class DEventHandler : public DObject // make it a part of normal GC process
{
DECLARE_CLASS(DEventHandler, DObject)
@ -23,6 +43,10 @@ public:
virtual void RenderFrame();
// called before entering each actor's view (including RenderFrame)
virtual void RenderCamera();
// called before adding each actor to the render list
virtual void RenderBeforeThing(AActor* thing);
// called after adding each actor to the render list
virtual void RenderAfterThing(AActor* thing);
};
extern DEventHandler* E_FirstEventHandler;
@ -30,31 +54,42 @@ class DRenderEventHandler : public DEventHandler
{
DECLARE_CLASS(DRenderEventHandler, DEventHandler)
public:
// these are for all render events
DVector3 ViewPos;
DAngle ViewAngle;
DAngle ViewPitch;
DAngle ViewRoll;
double FracTic; // 0..1 value that describes where we are inside the current gametic, render-wise.
// this makes sense in RenderCamera
AActor* Camera;
// this is for RenderBeforeThing and RenderAfterThing
AActor* CurrentThing;
void RenderFrame() override;
void RenderCamera() override;
void RenderBeforeThing(AActor* thing) override;
void RenderAfterThing(AActor* thing) override;
// this is a class that I use to automatically call RenderAfterThing.
// C++ is really horrible for not providing try-finally statement.
struct AutoThing
{
AActor* thing;
AutoThing(AActor* thing)
{
this->thing = thing;
E_RenderBeforeThing(this->thing);
}
~AutoThing()
{
E_RenderAfterThing(this->thing);
}
};
private:
void Setup();
};
// register
void E_RegisterHandler(DEventHandler* handler);
// unregister
void E_UnregisterHandler(DEventHandler* handler);
// called right after the map has loaded (approximately same time as OPEN ACS scripts)
void E_MapLoaded();
// called when the map is about to unload (approximately same time as UNLOADING ACS scripts)
void E_MapUnloading();
// called on each render frame once.
void E_RenderFrame();
// called before entering each actor's view (including RenderFrame)
void E_RenderCamera();
#endif

View File

@ -37,6 +37,7 @@
#include "a_pickups.h"
#include "d_player.h"
#include "g_levellocals.h"
#include "events.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"
@ -649,6 +650,8 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
if (thing == nullptr)
return;
DRenderEventHandler::AutoThing autoRenderThingEvent(thing);
// [ZZ] allow CustomSprite-style direct picnum specification
bool isPicnumOverride = thing->picnum.isValid();

View File

@ -66,6 +66,7 @@
#include "p_maputl.h"
#include "g_levellocals.h"
#include "r_thread.h"
#include "events.h"
EXTERN_CVAR(Bool, st_scale)
EXTERN_CVAR(Bool, r_shadercolormaps)
@ -1244,6 +1245,8 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside)
if (thing->validcount == validcount) continue;
thing->validcount = validcount;
DRenderEventHandler::AutoThing autoRenderThingEvent(thing);
FIntCVar *cvar = thing->GetClass()->distancecheck;
if (cvar != NULL && *cvar >= 0)
{

View File

@ -12,13 +12,20 @@ class EventHandler : Object native
virtual native void RenderFrame();
virtual native void RenderCamera();
virtual native void RenderBeforeThing();
virtual native void RenderAfterThing();
}
class RenderEventHandler : EventHandler native
{
// for frame and camera
native readonly Vector3 ViewPos;
native readonly double ViewAngle;
native readonly double ViewPitch;
native readonly double ViewRoll;
native readonly double FracTic;
// for camera
native readonly Actor Camera;
// for thing
native readonly Actor CurrentThing;
}