- Add per-pixel model light to the OpenGL 3.3 render path

This commit is contained in:
Magnus Norddahl 2018-03-01 01:27:12 +01:00
parent 6652df40c1
commit 48e534bf19
6 changed files with 84 additions and 10 deletions

View File

@ -331,6 +331,8 @@ void GLSceneDrawer::RenderScene(int recursion)
gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].DrawWalls(GLPASS_LIGHTSONLY);
gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].Draw(GLPASS_LIGHTSONLY);
gl_drawinfo->drawlists[GLDL_TRANSLUCENT].Draw(GLPASS_LIGHTSONLY, true);
gl_drawinfo->drawlists[GLDL_MODELS].Draw(GLPASS_LIGHTSONLY);
SetupWeaponLight();
GLRenderer->mLights->Finish();
}

View File

@ -14,6 +14,10 @@ class GLSceneDrawer
subsector_t *currentsubsector; // used by the line processing code.
sector_t *currentsector;
TMap<DPSprite*, int> weapondynlightindex;
void SetupWeaponLight();
void RenderMultipassStuff();
void UnclipSubsector(subsector_t *sub);

View File

@ -82,6 +82,7 @@ EXTERN_CVAR (Bool, r_debug_disable_vis_filter)
extern TArray<spritedef_t> sprites;
extern TArray<spriteframe_t> SpriteFrames;
extern uint32_t r_renderercaps;
extern int modellightindex;
enum HWRenderStyle
{
@ -263,7 +264,25 @@ void GLSprite::CalculateVertices(FVector3 *v)
void GLSprite::Draw(int pass)
{
if (pass == GLPASS_DECALS || pass == GLPASS_LIGHTSONLY) return;
if (pass == GLPASS_DECALS) return;
if (pass == GLPASS_LIGHTSONLY)
{
if (modelframe)
{
if (RenderStyle.BlendOp != STYLEOP_Shadow)
{
if (gl_lights && GLRenderer->mLightCount && mDrawer->FixedColormap == CM_DEFAULT && !fullbright)
{
if (!particle)
{
dynlightindex = gl_SetDynModelLight(gl_light_sprites ? actor : nullptr, -1);
}
}
}
}
return;
}
bool additivefog = false;
bool foglayer = false;
@ -336,7 +355,7 @@ void GLSprite::Draw(int pass)
if (gl_lights && GLRenderer->mLightCount && mDrawer->FixedColormap == CM_DEFAULT && !fullbright)
{
if (modelframe && !particle)
gl_SetDynModelLight(gl_light_sprites ? actor : NULL);
gl_SetDynModelLight(gl_light_sprites ? actor : NULL, dynlightindex);
else
gl_SetDynSpriteLight(gl_light_sprites ? actor : NULL, gl_light_particles ? particle : NULL);
}

View File

@ -198,13 +198,21 @@ void BSPWalkCircle(float x, float y, float radiusSquared, const Callback &callba
BSPNodeWalkCircle(level.HeadNode(), x, y, radiusSquared, callback);
}
void gl_SetDynModelLight(AActor *self)
int gl_SetDynModelLight(AActor *self, int dynlightindex)
{
// Legacy and deferred render paths gets the old flat model light
if (gl.lightmethod != LM_DIRECT)
// For deferred light mode this function gets called twice. First time for list upload, and second for draw.
if (gl.lightmethod == LM_DEFERRED && dynlightindex != -1)
{
gl_RenderState.SetDynLight(0, 0, 0);
modellightindex = dynlightindex;
return dynlightindex;
}
// Legacy render path gets the old flat model light
if (gl.lightmethod == LM_LEGACY)
{
gl_SetDynSpriteLight(self, nullptr);
return;
return -1;
}
modellightdata.Clear();
@ -249,6 +257,12 @@ void gl_SetDynModelLight(AActor *self)
});
}
gl_RenderState.SetDynLight(0, 0, 0);
modellightindex = GLRenderer->mLights->UploadLights(modellightdata);
dynlightindex = GLRenderer->mLights->UploadLights(modellightdata);
if (gl.lightmethod != LM_DEFERRED)
{
gl_RenderState.SetDynLight(0, 0, 0);
modellightindex = dynlightindex;
}
return dynlightindex;
}

View File

@ -392,6 +392,8 @@ public:
TArray<lightlist_t> *lightlist;
DRotator Angles;
int dynlightindex;
void SplitSprite(sector_t * frontsector, bool translucent);
void SetLowerParam();
void PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingpos, float spriteheight);
@ -422,6 +424,6 @@ inline float Dist2(float x1,float y1,float x2,float y2)
void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *subsec);
void gl_SetDynSpriteLight(AActor *actor, particle_t *particle);
void gl_SetDynModelLight(AActor *self);
int gl_SetDynModelLight(AActor *self, int dynlightindex);
#endif

View File

@ -183,6 +183,39 @@ static bool isBright(DPSprite *psp)
return false;
}
void GLSceneDrawer::SetupWeaponLight()
{
weapondynlightindex.Clear();
AActor *camera = r_viewpoint.camera;
AActor * playermo = players[consoleplayer].camera;
player_t * player = playermo->player;
// this is the same as in DrawPlayerSprites below
if (!player ||
!r_drawplayersprites ||
!camera->player ||
(player->cheats & CF_CHASECAM) ||
(r_deathcamera && camera->health <= 0))
return;
for (DPSprite *psp = player->psprites; psp != nullptr && psp->GetID() < PSP_TARGETCENTER; psp = psp->GetNext())
{
if (psp->GetState() != nullptr)
{
// set the lighting parameters
if (gl_lights && GLRenderer->mLightCount && FixedColormap == CM_DEFAULT && gl_light_sprites)
{
FSpriteModelFrame *smf = playermo->player->ReadyWeapon ? gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false) : nullptr;
if (smf)
{
weapondynlightindex[psp] = gl_SetDynModelLight(playermo, -1);
}
}
}
}
}
//==========================================================================
//
// R_DrawPlayerSprites
@ -422,7 +455,7 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
{
FSpriteModelFrame *smf = playermo->player->ReadyWeapon ? gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false) : nullptr;
if (smf)
gl_SetDynModelLight(playermo);
gl_SetDynModelLight(playermo, weapondynlightindex[psp]);
else
gl_SetDynSpriteLight(playermo, NULL);
}