mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-03-17 08:21:28 +00:00
Merge branch 'master' of https://github.com/coelckers/gzdoom
This commit is contained in:
commit
61c11e513b
20 changed files with 901 additions and 181 deletions
|
@ -401,6 +401,7 @@ enum ActorFlag8
|
|||
{
|
||||
MF8_FRIGHTENING = 0x00000001, // for those moments when halloween just won't do
|
||||
MF8_INSCROLLSEC = 0x00000002, // actor is partially inside a scrolling sector
|
||||
MF8_BLOCKASPLAYER = 0x00000004, // actor is blocked by player-blocking lines even if not a player
|
||||
};
|
||||
|
||||
// --- mobj.renderflags ---
|
||||
|
|
|
@ -210,44 +210,47 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool
|
|||
auto vcount = flat->sector->ibocount;
|
||||
|
||||
gl_RenderState.Apply();
|
||||
auto iboindex = flat->iboindex;
|
||||
if (gl.legacyMode)
|
||||
{
|
||||
processlights = false;
|
||||
goto legacy;
|
||||
iboindex = -1;
|
||||
}
|
||||
|
||||
if (vcount > 0 && !gl_RenderState.GetClipLineShouldBeActive())
|
||||
if (iboindex >= 0)
|
||||
{
|
||||
if (processlights) SetupSectorLights(flat, GLPASS_ALL, &dli);
|
||||
drawcalls.Clock();
|
||||
glDrawElements(GL_TRIANGLES, vcount, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + flat->iboindex);
|
||||
drawcalls.Unclock();
|
||||
flatvertices += vcount;
|
||||
flatprimitives++;
|
||||
}
|
||||
else if (flat->iboindex >= 0)
|
||||
{
|
||||
int index = flat->iboindex;
|
||||
for (int i=0; i<flat->sector->subsectorcount; i++)
|
||||
if (vcount > 0 && !gl_RenderState.GetClipLineShouldBeActive())
|
||||
{
|
||||
subsector_t * sub = flat->sector->subsectors[i];
|
||||
if (sub->numlines <= 2) continue;
|
||||
|
||||
if (ss_renderflags[sub->Index()]& flat->renderflags || istrans)
|
||||
if (processlights) SetupSectorLights(flat, GLPASS_ALL, &dli);
|
||||
drawcalls.Clock();
|
||||
glDrawElements(GL_TRIANGLES, vcount, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + iboindex);
|
||||
drawcalls.Unclock();
|
||||
flatvertices += vcount;
|
||||
flatprimitives++;
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = iboindex;
|
||||
for (int i = 0; i < flat->sector->subsectorcount; i++)
|
||||
{
|
||||
if (processlights) SetupSubsectorLights(flat, GLPASS_ALL, sub, &dli);
|
||||
drawcalls.Clock();
|
||||
glDrawElements(GL_TRIANGLES, (sub->numlines - 2) * 3, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + index);
|
||||
drawcalls.Unclock();
|
||||
flatvertices += sub->numlines;
|
||||
flatprimitives++;
|
||||
subsector_t * sub = flat->sector->subsectors[i];
|
||||
if (sub->numlines <= 2) continue;
|
||||
|
||||
if (ss_renderflags[sub->Index()] & flat->renderflags || istrans)
|
||||
{
|
||||
if (processlights) SetupSubsectorLights(flat, GLPASS_ALL, sub, &dli);
|
||||
drawcalls.Clock();
|
||||
glDrawElements(GL_TRIANGLES, (sub->numlines - 2) * 3, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + index);
|
||||
drawcalls.Unclock();
|
||||
flatvertices += sub->numlines;
|
||||
flatprimitives++;
|
||||
}
|
||||
index += (sub->numlines - 2) * 3;
|
||||
}
|
||||
index += (sub->numlines - 2) * 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
legacy:
|
||||
// Draw the subsectors belonging to this sector
|
||||
for (int i=0; i<flat->sector->subsectorcount; i++)
|
||||
{
|
||||
|
|
|
@ -46,6 +46,7 @@ struct FMemArena::Block
|
|||
Block *NextBlock;
|
||||
void *Limit; // End of this block
|
||||
void *Avail; // Start of free space in this block
|
||||
void *alignme; // align to 16 bytes.
|
||||
|
||||
void Reset();
|
||||
void *Alloc(size_t size);
|
||||
|
@ -94,7 +95,7 @@ FMemArena::~FMemArena()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void *FMemArena::Alloc(size_t size)
|
||||
void *FMemArena::iAlloc(size_t size)
|
||||
{
|
||||
Block *block;
|
||||
|
||||
|
@ -110,6 +111,11 @@ void *FMemArena::Alloc(size_t size)
|
|||
return block->Alloc(size);
|
||||
}
|
||||
|
||||
void *FMemArena::Alloc(size_t size)
|
||||
{
|
||||
return iAlloc((size + 15) & ~15);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FMemArena :: FreeAll
|
||||
|
@ -316,7 +322,7 @@ FString *FSharedStringArena::Alloc(const FString &source)
|
|||
strnode = FindString(source, source.Len(), hash);
|
||||
if (strnode == NULL)
|
||||
{
|
||||
strnode = (Node *)FMemArena::Alloc(sizeof(Node));
|
||||
strnode = (Node *)iAlloc(sizeof(Node));
|
||||
::new(&strnode->String) FString(source);
|
||||
strnode->Hash = hash;
|
||||
hash %= countof(Buckets);
|
||||
|
@ -351,7 +357,7 @@ FString *FSharedStringArena::Alloc(const char *source, size_t strlen)
|
|||
strnode = FindString(source, strlen, hash);
|
||||
if (strnode == NULL)
|
||||
{
|
||||
strnode = (Node *)FMemArena::Alloc(sizeof(Node));
|
||||
strnode = (Node *)iAlloc(sizeof(Node));
|
||||
::new(&strnode->String) FString(source, strlen);
|
||||
strnode->Hash = hash;
|
||||
hash %= countof(Buckets);
|
||||
|
|
|
@ -54,6 +54,7 @@ protected:
|
|||
|
||||
Block *AddBlock(size_t size);
|
||||
void FreeBlockChain(Block *&top);
|
||||
void *iAlloc(size_t size);
|
||||
|
||||
Block *TopBlock;
|
||||
Block *FreeBlocks;
|
||||
|
|
|
@ -714,7 +714,9 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
|
|||
tics = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
// The following condition is needed to avoid crash when player class has no death states
|
||||
// Instance of player pawn will be garbage collected on reloading of level
|
||||
else if (player == nullptr)
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
|
|
@ -930,7 +930,10 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
|
|||
bool NotBlocked = ((tm.thing->flags3 & MF3_NOBLOCKMONST)
|
||||
|| ((i_compatflags & COMPATF_NOBLOCKFRIENDS) && (tm.thing->flags & MF_FRIENDLY)));
|
||||
|
||||
if (!(Projectile) || (ld->flags & (ML_BLOCKEVERYTHING | ML_BLOCKPROJECTILE)))
|
||||
uint32_t ProjectileBlocking = ML_BLOCKEVERYTHING | ML_BLOCKPROJECTILE;
|
||||
if ( tm.thing->flags8 & MF8_BLOCKASPLAYER ) ProjectileBlocking |= ML_BLOCK_PLAYERS | ML_BLOCKING;
|
||||
|
||||
if (!(Projectile) || (ld->flags & ProjectileBlocking) )
|
||||
{
|
||||
if (ld->flags & ML_RAILING)
|
||||
{
|
||||
|
@ -938,7 +941,7 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
|
|||
}
|
||||
else if ((ld->flags & (ML_BLOCKING | ML_BLOCKEVERYTHING)) || // explicitly blocking everything
|
||||
(!(NotBlocked) && (ld->flags & ML_BLOCKMONSTERS)) || // block monsters only
|
||||
(tm.thing->player != NULL && (ld->flags & ML_BLOCK_PLAYERS)) || // block players
|
||||
(((tm.thing->player != NULL) || (tm.thing->flags8 & MF8_BLOCKASPLAYER)) && (ld->flags & ML_BLOCK_PLAYERS)) || // block players
|
||||
((Projectile) && (ld->flags & ML_BLOCKPROJECTILE)) || // block projectiles
|
||||
((tm.thing->flags & MF_FLOAT) && (ld->flags & ML_BLOCK_FLOATERS))) // block floaters
|
||||
{
|
||||
|
@ -3100,7 +3103,7 @@ void FSlide::SlideTraverse(const DVector2 &start, const DVector2 &end)
|
|||
{
|
||||
goto isblocking;
|
||||
}
|
||||
if (li->flags & ML_BLOCK_PLAYERS && slidemo->player != NULL)
|
||||
if (li->flags & ML_BLOCK_PLAYERS && ((slidemo->player != NULL) || (slidemo->flags8 & MF8_BLOCKASPLAYER)))
|
||||
{
|
||||
goto isblocking;
|
||||
}
|
||||
|
@ -4195,11 +4198,38 @@ struct aim_t
|
|||
thingtoppitch = -VecToAngle(dist, th->Top() - shootz);
|
||||
|
||||
if (thingtoppitch > bottompitch)
|
||||
continue; // shot over the thing
|
||||
{
|
||||
// Check for a hit from above
|
||||
if (shootz > th->Top())
|
||||
{
|
||||
double exitfrac = ExitPoint(th);
|
||||
if (exitfrac > 0.)
|
||||
{
|
||||
double exitdist = attackrange * exitfrac;
|
||||
thingtoppitch = -VecToAngle(exitdist, th->Top() - shootz);
|
||||
if (thingtoppitch > bottompitch) continue;
|
||||
}
|
||||
else continue; // shot over the thing
|
||||
}
|
||||
else continue; // shot over the thing
|
||||
}
|
||||
|
||||
thingbottompitch = -VecToAngle(dist, th->Z() - shootz);
|
||||
|
||||
if (thingbottompitch < toppitch)
|
||||
{
|
||||
// Check for a hit from below
|
||||
if (shootz < th->Z())
|
||||
{
|
||||
double exitfrac = ExitPoint(th);
|
||||
if (exitfrac > 0.)
|
||||
{
|
||||
double exitdist = attackrange * exitfrac;
|
||||
thingbottompitch = -VecToAngle(exitdist, th->Z() - shootz);
|
||||
if (thingbottompitch < toppitch) continue;
|
||||
}
|
||||
else continue; // shot over the thing
|
||||
}
|
||||
continue; // shot under the thing
|
||||
|
||||
if (crossedffloors)
|
||||
|
|
|
@ -589,7 +589,15 @@ void P_GiveSecret(AActor *actor, bool printmessage, bool playsound, int sectornu
|
|||
{
|
||||
actor->player->secretcount++;
|
||||
}
|
||||
if (cl_showsecretmessage && actor->CheckLocalView(consoleplayer))
|
||||
int retval = 1;
|
||||
IFVIRTUALPTR(actor, AActor, OnGiveSecret)
|
||||
{
|
||||
VMValue params[] = { actor, printmessage, playsound };
|
||||
VMReturn ret;
|
||||
ret.IntAt(&retval);
|
||||
VMCall(func, params, countof(params), &ret, 1);
|
||||
}
|
||||
if (retval && cl_showsecretmessage && actor->CheckLocalView(consoleplayer))
|
||||
{
|
||||
if (printmessage)
|
||||
{
|
||||
|
@ -616,6 +624,7 @@ DEFINE_ACTION_FUNCTION(AActor, GiveSecret)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FLevelLocals, GiveSecret)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
|
|
|
@ -1157,7 +1157,7 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd)
|
|||
// [TN] Check wether this actor gets blocked by the line.
|
||||
if (ld->backsector != NULL &&
|
||||
!(ld->flags & (ML_BLOCKING|ML_BLOCKEVERYTHING))
|
||||
&& !(ld->flags & ML_BLOCK_PLAYERS && mobj->player)
|
||||
&& !(ld->flags & ML_BLOCK_PLAYERS && (mobj->player || (mobj->flags8 & MF8_BLOCKASPLAYER)))
|
||||
&& !(ld->flags & ML_BLOCKMONSTERS && mobj->flags3 & MF3_ISMONSTER)
|
||||
&& !((mobj->flags & MF_FLOAT) && (ld->flags & ML_BLOCK_FLOATERS))
|
||||
&& (!(ld->flags & ML_3DMIDTEX) ||
|
||||
|
|
|
@ -106,15 +106,24 @@ void PolyDrawArgs::SetLight(FSWColormap *base_colormap, uint32_t lightlevel, dou
|
|||
|
||||
mLight = clamp<uint32_t>(lightlevel, 0, 255);
|
||||
mFixedLight = fixed;
|
||||
mLightRed = base_colormap->Color.r * 256 / 255;
|
||||
mLightGreen = base_colormap->Color.g * 256 / 255;
|
||||
mLightBlue = base_colormap->Color.b * 256 / 255;
|
||||
mLightAlpha = base_colormap->Color.a * 256 / 255;
|
||||
mLightRed = base_colormap->Color.r;
|
||||
mLightRed += mLightRed >> 7;
|
||||
mLightGreen = base_colormap->Color.g;
|
||||
mLightGreen += mLightGreen >> 7;
|
||||
mLightBlue = base_colormap->Color.b;
|
||||
mLightBlue += mLightBlue >> 7;
|
||||
mLightAlpha = base_colormap->Color.a;
|
||||
mLightAlpha += mLightAlpha >> 7;
|
||||
mFadeRed = base_colormap->Fade.r;
|
||||
mFadeRed += mFadeRed >> 7;
|
||||
mFadeGreen = base_colormap->Fade.g;
|
||||
mFadeGreen += mFadeGreen >> 7;
|
||||
mFadeBlue = base_colormap->Fade.b;
|
||||
mFadeBlue += mFadeBlue >> 7;
|
||||
mFadeAlpha = base_colormap->Fade.a;
|
||||
mDesaturate = MIN(abs(base_colormap->Desaturate), 255) * 255 / 256;
|
||||
mFadeAlpha += mFadeAlpha >> 7;
|
||||
mDesaturate = MIN(abs(base_colormap->Desaturate), 255);
|
||||
mDesaturate += mDesaturate >> 7;
|
||||
mSimpleShade = (base_colormap->Color.d == 0x00ffffff && base_colormap->Fade.d == 0x00000000 && base_colormap->Desaturate == 0);
|
||||
mColormaps = base_colormap->Maps;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -757,8 +757,8 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
|
|||
{
|
||||
// listener must be reversely offset to calculate the proper sound origin.
|
||||
CalcSectorSoundOrg(listenpos + disp, sector, channum, *pos);
|
||||
pos->X += (float)disp.X;
|
||||
pos->Z += (float)disp.Y;
|
||||
pos->X -= (float)disp.X;
|
||||
pos->Z -= (float)disp.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -316,6 +316,7 @@ static FFlagDef ActorFlagDefs[]=
|
|||
DEFINE_FLAG(MF7, FORCEINFIGHTING, AActor, flags7),
|
||||
|
||||
DEFINE_FLAG(MF8, FRIGHTENING, AActor, flags8),
|
||||
DEFINE_FLAG(MF8, BLOCKASPLAYER, AActor, flags8),
|
||||
|
||||
// Effect flags
|
||||
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
|
||||
|
|
|
@ -189,7 +189,12 @@ namespace swrenderer
|
|||
{
|
||||
auto viewport = Thread->Viewport.get();
|
||||
|
||||
drawerargs.dc_viewpos.X = (float)((x + 0.5 - viewport->CenterX) / viewport->CenterX * zcol);
|
||||
int tx = x;
|
||||
bool mirror = !!(Thread->Portal->MirrorFlags & RF_XFLIP);
|
||||
if (mirror)
|
||||
tx = viewwidth - tx - 1;
|
||||
|
||||
drawerargs.dc_viewpos.X = (float)((tx + 0.5 - viewport->CenterX) / viewport->CenterX * zcol);
|
||||
drawerargs.dc_viewpos.Y = zcol;
|
||||
drawerargs.dc_viewpos.Z = (float)((viewport->CenterY - y1 - 0.5) / viewport->InvZtoScale * zcol);
|
||||
drawerargs.dc_viewpos_step.Z = (float)(-zcol / viewport->InvZtoScale);
|
||||
|
|
|
@ -205,13 +205,21 @@ namespace swrenderer
|
|||
|
||||
if (r_dynlights)
|
||||
{
|
||||
int tx = x1;
|
||||
bool mirror = !!(Thread->Portal->MirrorFlags & RF_XFLIP);
|
||||
if (mirror)
|
||||
tx = viewwidth - tx - 1;
|
||||
|
||||
// Find row position in view space
|
||||
float zspan = (float)(planeheight / (fabs(y + 0.5 - viewport->CenterY) / viewport->InvZtoScale));
|
||||
drawerargs.dc_viewpos.X = (float)((x1 + 0.5 - viewport->CenterX) / viewport->CenterX * zspan);
|
||||
drawerargs.dc_viewpos.X = (float)((tx + 0.5 - viewport->CenterX) / viewport->CenterX * zspan);
|
||||
drawerargs.dc_viewpos.Y = zspan;
|
||||
drawerargs.dc_viewpos.Z = (float)((viewport->CenterY - y - 0.5) / viewport->InvZtoScale * zspan);
|
||||
drawerargs.dc_viewpos_step.X = (float)(zspan / viewport->CenterX);
|
||||
|
||||
if (mirror)
|
||||
drawerargs.dc_viewpos_step.X = -drawerargs.dc_viewpos_step.X;
|
||||
|
||||
// Plane normal
|
||||
drawerargs.dc_normal.X = 0.0f;
|
||||
drawerargs.dc_normal.Y = 0.0f;
|
||||
|
|
|
@ -173,6 +173,7 @@ namespace swrenderer
|
|||
Thread->Viewport->viewpoint.sector = port->mDestination;
|
||||
assert(Thread->Viewport->viewpoint.sector != nullptr);
|
||||
R_SetViewAngle(Thread->Viewport->viewpoint, Thread->Viewport->viewwindow);
|
||||
Thread->Viewport->SetupPolyViewport(Thread);
|
||||
Thread->OpaquePass->ClearSeenSprites();
|
||||
Thread->Clip3D->ClearFakeFloors();
|
||||
|
||||
|
@ -239,6 +240,7 @@ namespace swrenderer
|
|||
// Masked textures and planes need the view coordinates restored for proper positioning.
|
||||
viewposStack.Pop(Thread->Viewport->viewpoint.Pos);
|
||||
|
||||
Thread->Viewport->SetupPolyViewport(Thread);
|
||||
Thread->TranslucentPass->Render();
|
||||
|
||||
VisiblePlane *pl = nullptr; // quiet, GCC!
|
||||
|
@ -259,6 +261,7 @@ namespace swrenderer
|
|||
Thread->Viewport->viewpoint.extralight = savedextralight;
|
||||
Thread->Viewport->viewpoint.Angles = savedangles;
|
||||
R_SetViewAngle(Thread->Viewport->viewpoint, Thread->Viewport->viewwindow);
|
||||
Thread->Viewport->SetupPolyViewport(Thread);
|
||||
|
||||
CurrentPortalInSkybox = false;
|
||||
Thread->Clip3D->LeaveSkybox();
|
||||
|
@ -426,6 +429,8 @@ namespace swrenderer
|
|||
else MirrorFlags |= RF_XFLIP;
|
||||
}
|
||||
|
||||
Thread->Viewport->SetupPolyViewport(Thread);
|
||||
|
||||
// some portals have height differences, account for this here
|
||||
Thread->Clip3D->EnterSkybox(); // push 3D floor height map
|
||||
CurrentPortalInSkybox = false; // first portal in a skybox should set this variable to false for proper clipping in skyboxes.
|
||||
|
@ -478,6 +483,8 @@ namespace swrenderer
|
|||
viewpoint.Pos = startpos;
|
||||
viewpoint.Path[0] = savedpath[0];
|
||||
viewpoint.Path[1] = savedpath[1];
|
||||
|
||||
viewport->SetupPolyViewport(Thread);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -159,6 +159,8 @@ namespace swrenderer
|
|||
if (r_models)
|
||||
MainThread()->Viewport->SetupPolyViewport(MainThread());
|
||||
|
||||
FRenderViewpoint origviewpoint = MainThread()->Viewport->viewpoint;
|
||||
|
||||
ActorRenderFlags savedflags = MainThread()->Viewport->viewpoint.camera->renderflags;
|
||||
// Never draw the player unless in chasecam mode
|
||||
if (!MainThread()->Viewport->viewpoint.showviewer)
|
||||
|
@ -167,6 +169,12 @@ namespace swrenderer
|
|||
}
|
||||
|
||||
RenderThreadSlices();
|
||||
|
||||
// Mirrors fail to restore the original viewpoint -- we need it for the HUD weapon to draw correctly.
|
||||
MainThread()->Viewport->viewpoint = origviewpoint;
|
||||
if (r_models)
|
||||
MainThread()->Viewport->SetupPolyViewport(MainThread());
|
||||
|
||||
RenderPSprites();
|
||||
|
||||
MainThread()->Viewport->viewpoint.camera->renderflags = savedflags;
|
||||
|
|
|
@ -47,12 +47,22 @@ namespace swrenderer
|
|||
if (tz < MINZ)
|
||||
return;
|
||||
|
||||
// too far off the side?
|
||||
double tx = tr_x * thread->Viewport->viewpoint.Sin - tr_y * thread->Viewport->viewpoint.Cos;
|
||||
|
||||
// Flip for mirrors
|
||||
if (thread->Portal->MirrorFlags & RF_XFLIP)
|
||||
{
|
||||
tx = viewwidth - tx - 1;
|
||||
}
|
||||
|
||||
// too far off the side?
|
||||
if (fabs(tx / 64) > fabs(tz))
|
||||
return;
|
||||
|
||||
RenderModel *vis = thread->FrameMemory->NewObject<RenderModel>(x, y, z, smf, actor, float(1 / tz));
|
||||
vis->CurrentPortalUniq = thread->Portal->CurrentPortalUniq;
|
||||
vis->WorldToClip = thread->Viewport->WorldToClip;
|
||||
vis->MirrorWorldToClip = !!(thread->Portal->MirrorFlags & RF_XFLIP);
|
||||
thread->SpriteList->Push(vis);
|
||||
}
|
||||
|
||||
|
@ -64,7 +74,7 @@ namespace swrenderer
|
|||
|
||||
void RenderModel::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor)
|
||||
{
|
||||
SWModelRenderer renderer(thread, clip3DFloor);
|
||||
SWModelRenderer renderer(thread, clip3DFloor, &WorldToClip, MirrorWorldToClip);
|
||||
renderer.RenderModel(x, y, z, smf, actor);
|
||||
}
|
||||
|
||||
|
@ -72,13 +82,14 @@ namespace swrenderer
|
|||
|
||||
void RenderHUDModel(RenderThread *thread, DPSprite *psp, float ofsx, float ofsy)
|
||||
{
|
||||
SWModelRenderer renderer(thread, Fake3DTranslucent());
|
||||
SWModelRenderer renderer(thread, Fake3DTranslucent(), &thread->Viewport->WorldToClip, false);
|
||||
renderer.RenderHUDModel(psp, ofsx, ofsy);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SWModelRenderer::SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor) : Thread(thread), Clip3DFloor(clip3DFloor)
|
||||
SWModelRenderer::SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor, Mat4f *worldToClip, bool mirrorWorldToClip)
|
||||
: Thread(thread), Clip3DFloor(clip3DFloor), WorldToClip(worldToClip), MirrorWorldToClip(mirrorWorldToClip)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -123,6 +134,7 @@ namespace swrenderer
|
|||
|
||||
if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES))
|
||||
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
|
||||
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, !(mirrored ^ MirrorWorldToClip));
|
||||
}
|
||||
|
||||
void SWModelRenderer::EndDrawModel(AActor *actor, FSpriteModelFrame *smf)
|
||||
|
@ -192,6 +204,7 @@ namespace swrenderer
|
|||
|
||||
if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal])
|
||||
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
|
||||
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, !(mirrored ^ MirrorWorldToClip));
|
||||
}
|
||||
|
||||
void SWModelRenderer::EndDrawHUDModel(AActor *actor)
|
||||
|
@ -221,7 +234,7 @@ namespace swrenderer
|
|||
swapYZ.Matrix[2 + 1 * 4] = 1.0f;
|
||||
swapYZ.Matrix[3 + 3 * 4] = 1.0f;
|
||||
|
||||
PolyTriangleDrawer::SetTransform(Thread->DrawQueue, Thread->FrameMemory->NewObject<Mat4f>(Thread->Viewport->WorldToClip * swapYZ * ObjectToWorld));
|
||||
PolyTriangleDrawer::SetTransform(Thread->DrawQueue, Thread->FrameMemory->NewObject<Mat4f>((*WorldToClip) * swapYZ * ObjectToWorld));
|
||||
}
|
||||
|
||||
void SWModelRenderer::DrawArrays(int start, int count)
|
||||
|
|
|
@ -47,12 +47,14 @@ namespace swrenderer
|
|||
float x, y, z;
|
||||
FSpriteModelFrame *smf;
|
||||
AActor *actor;
|
||||
Mat4f WorldToClip;
|
||||
bool MirrorWorldToClip;
|
||||
};
|
||||
|
||||
class SWModelRenderer : public FModelRenderer
|
||||
{
|
||||
public:
|
||||
SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor);
|
||||
SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor, Mat4f *worldToClip, bool mirrorWorldToClip);
|
||||
|
||||
ModelRendererType GetType() const override { return SWModelRendererType; }
|
||||
|
||||
|
@ -81,6 +83,8 @@ namespace swrenderer
|
|||
unsigned int *IndexBuffer = nullptr;
|
||||
TriVertex *VertexBuffer = nullptr;
|
||||
float InterpolationFactor = 0.0;
|
||||
Mat4f *WorldToClip = nullptr;
|
||||
bool MirrorWorldToClip = false;
|
||||
};
|
||||
|
||||
class SWModelVertexBuffer : public IModelVertexBuffer
|
||||
|
|
|
@ -62,6 +62,10 @@ namespace swrenderer
|
|||
void RenderViewport::SetupPolyViewport(RenderThread *thread)
|
||||
{
|
||||
WorldToView = SoftwareWorldToView(viewpoint);
|
||||
|
||||
if (thread->Portal->MirrorFlags & RF_XFLIP)
|
||||
WorldToView = Mat4f::Scale(-1.0f, 1.0f, 1.0f) * WorldToView;
|
||||
|
||||
ViewToClip = SoftwareViewToClip();
|
||||
WorldToClip = ViewToClip * WorldToView;
|
||||
}
|
||||
|
|
|
@ -539,6 +539,9 @@ class Actor : Thinker native
|
|||
{
|
||||
return damage;
|
||||
}
|
||||
|
||||
// called on getting a secret, return false to disable default "secret found" message/sound
|
||||
virtual bool OnGiveSecret(bool printmsg, bool playsound) { return true; }
|
||||
|
||||
native virtual bool OkayToSwitchTarget(Actor other);
|
||||
native static class<Actor> GetReplacement(class<Actor> cls);
|
||||
|
|
Loading…
Reference in a new issue