Added per-thing render hooks

This commit is contained in:
ZZYZX 2017-01-22 07:04:35 +02:00
parent 5bfd484ae2
commit 302af61686
5 changed files with 97 additions and 20 deletions

View file

@ -53,6 +53,18 @@ void E_RenderCamera()
handler->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 // declarations
IMPLEMENT_CLASS(DEventHandler, false, false); IMPLEMENT_CLASS(DEventHandler, false, false);
IMPLEMENT_CLASS(DRenderEventHandler, 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, ViewPitch);
DEFINE_FIELD_X(RenderEventHandler, DRenderEventHandler, ViewRoll); DEFINE_FIELD_X(RenderEventHandler, DRenderEventHandler, ViewRoll);
DEFINE_FIELD_X(RenderEventHandler, DRenderEventHandler, FracTic); DEFINE_FIELD_X(RenderEventHandler, DRenderEventHandler, FracTic);
DEFINE_FIELD_X(RenderEventHandler, DRenderEventHandler, Camera);
DEFINE_FIELD_X(RenderEventHandler, DRenderEventHandler, CurrentThing);
DEFINE_ACTION_FUNCTION(DEventHandler, Create) DEFINE_ACTION_FUNCTION(DEventHandler, Create)
{ {
@ -109,12 +123,12 @@ DEFINE_ACTION_FUNCTION(DEventHandler, Unregister)
return 0; 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); \ PARAM_SELF_PROLOGUE(cls); \
return 0; \ return 0; \
} \ } \
void cls::funcname() \ void cls::funcname(args) \
{ \ { \
IFVIRTUAL(cls, funcname) \ IFVIRTUAL(cls, funcname) \
{ \ { \
@ -125,10 +139,12 @@ void cls::funcname() \
} \ } \
} }
DEFINE_EVENT_HANDLER(DEventHandler, MapLoaded) DEFINE_EVENT_HANDLER(DEventHandler, MapLoaded,)
DEFINE_EVENT_HANDLER(DEventHandler, MapUnloading) DEFINE_EVENT_HANDLER(DEventHandler, MapUnloading,)
DEFINE_EVENT_HANDLER(DEventHandler, RenderFrame) DEFINE_EVENT_HANDLER(DEventHandler, RenderFrame,)
DEFINE_EVENT_HANDLER(DEventHandler, RenderCamera) DEFINE_EVENT_HANDLER(DEventHandler, RenderCamera,)
DEFINE_EVENT_HANDLER(DEventHandler, RenderBeforeThing, AActor*)
DEFINE_EVENT_HANDLER(DEventHandler, RenderAfterThing, AActor*)
// //
void DEventHandler::OnDestroy() void DEventHandler::OnDestroy()
@ -144,6 +160,7 @@ void DRenderEventHandler::Setup()
ViewPitch = ::ViewPitch; ViewPitch = ::ViewPitch;
ViewRoll = ::ViewRoll; ViewRoll = ::ViewRoll;
FracTic = ::r_TicFracF; FracTic = ::r_TicFracF;
Camera = ::camera;
} }
void DRenderEventHandler::RenderFrame() void DRenderEventHandler::RenderFrame()
@ -157,3 +174,15 @@ void DRenderEventHandler::RenderCamera()
Setup(); Setup();
DEventHandler::RenderCamera(); 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" #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 class DEventHandler : public DObject // make it a part of normal GC process
{ {
DECLARE_CLASS(DEventHandler, DObject) DECLARE_CLASS(DEventHandler, DObject)
@ -23,6 +43,10 @@ public:
virtual void RenderFrame(); virtual void RenderFrame();
// called before entering each actor's view (including RenderFrame) // called before entering each actor's view (including RenderFrame)
virtual void RenderCamera(); 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; extern DEventHandler* E_FirstEventHandler;
@ -30,31 +54,42 @@ class DRenderEventHandler : public DEventHandler
{ {
DECLARE_CLASS(DRenderEventHandler, DEventHandler) DECLARE_CLASS(DRenderEventHandler, DEventHandler)
public: public:
// these are for all render events
DVector3 ViewPos; DVector3 ViewPos;
DAngle ViewAngle; DAngle ViewAngle;
DAngle ViewPitch; DAngle ViewPitch;
DAngle ViewRoll; DAngle ViewRoll;
double FracTic; // 0..1 value that describes where we are inside the current gametic, render-wise. 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 RenderFrame() override;
void RenderCamera() 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: private:
void Setup(); 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 #endif

View file

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

View file

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

View file

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