mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
This commit is contained in:
commit
d1c6d8543b
7 changed files with 145 additions and 28 deletions
|
@ -115,9 +115,9 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines)
|
||||||
|
|
||||||
DontMapLines = dontmaplines;
|
DontMapLines = dontmaplines;
|
||||||
|
|
||||||
|
R_SetupFrame(Viewpoint, Viewwindow, actor);
|
||||||
P_FindParticleSubsectors();
|
P_FindParticleSubsectors();
|
||||||
PO_LinkToSubsectors();
|
PO_LinkToSubsectors();
|
||||||
R_SetupFrame(Viewpoint, Viewwindow, actor);
|
|
||||||
|
|
||||||
if (APART(R_OldBlend)) NormalLight.Maps = realcolormaps.Maps;
|
if (APART(R_OldBlend)) NormalLight.Maps = realcolormaps.Maps;
|
||||||
else NormalLight.Maps = realcolormaps.Maps + NUMCOLORMAPS * 256 * R_OldBlend;
|
else NormalLight.Maps = realcolormaps.Maps + NUMCOLORMAPS * 256 * R_OldBlend;
|
||||||
|
|
|
@ -111,25 +111,48 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub)
|
||||||
|
|
||||||
uint32_t subsectorDepth = NextSubsectorDepth++;
|
uint32_t subsectorDepth = NextSubsectorDepth++;
|
||||||
|
|
||||||
|
bool mainBSP = sub->polys == nullptr;
|
||||||
|
|
||||||
|
if (sub->polys)
|
||||||
|
{
|
||||||
|
if (sub->BSP == nullptr || sub->BSP->bDirty)
|
||||||
|
{
|
||||||
|
sub->BuildPolyBSP();
|
||||||
|
|
||||||
|
// This is done by the GL renderer, but not the sw renderer. No idea what the purpose is..
|
||||||
|
for (unsigned i = 0; i < sub->BSP->Segs.Size(); i++)
|
||||||
|
{
|
||||||
|
sub->BSP->Segs[i].Subsector = sub;
|
||||||
|
sub->BSP->Segs[i].PartnerSeg = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sub->BSP->Nodes.Size() == 0)
|
||||||
|
{
|
||||||
|
RenderPolySubsector(&sub->BSP->Subsectors[0], subsectorDepth, frontsector);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RenderPolyNode(&sub->BSP->Nodes.Last(), subsectorDepth, frontsector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||||
|
{
|
||||||
|
seg_t *line = &sub->firstline[i];
|
||||||
|
RenderLine(sub, line, frontsector, subsectorDepth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (sub->sector->CenterFloor() != sub->sector->CenterCeiling())
|
if (sub->sector->CenterFloor() != sub->sector->CenterCeiling())
|
||||||
{
|
{
|
||||||
RenderPolyPlane::RenderPlanes(WorldToClip, PortalPlane, Cull, sub, subsectorDepth, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals);
|
RenderPolyPlane::RenderPlanes(WorldToClip, PortalPlane, Cull, sub, subsectorDepth, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
|
||||||
{
|
|
||||||
seg_t *line = &sub->firstline[i];
|
|
||||||
if (line->sidedef == nullptr || !(line->sidedef->Flags & WALLF_POLYOBJ))
|
|
||||||
{
|
|
||||||
RenderLine(sub, line, frontsector, subsectorDepth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderMemory &memory = PolyRenderer::Instance()->FrameMemory;
|
|
||||||
|
|
||||||
bool mainBSP = ((unsigned int)(sub->Index()) < level.subsectors.Size());
|
|
||||||
if (mainBSP)
|
if (mainBSP)
|
||||||
{
|
{
|
||||||
|
RenderMemory &memory = PolyRenderer::Instance()->FrameMemory;
|
||||||
int subsectorIndex = sub->Index();
|
int subsectorIndex = sub->Index();
|
||||||
for (int i = ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Particles[i].snext)
|
for (int i = ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Particles[i].snext)
|
||||||
{
|
{
|
||||||
|
@ -142,6 +165,73 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub)
|
||||||
SubsectorDepths[sub] = subsectorDepth;
|
SubsectorDepths[sub] = subsectorDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderPolyScene::RenderPolyNode(void *node, uint32_t subsectorDepth, sector_t *frontsector)
|
||||||
|
{
|
||||||
|
while (!((size_t)node & 1)) // Keep going until found a subsector
|
||||||
|
{
|
||||||
|
node_t *bsp = (node_t *)node;
|
||||||
|
|
||||||
|
// Decide which side the view point is on.
|
||||||
|
int side = PointOnSide(PolyRenderer::Instance()->Viewpoint.Pos, bsp);
|
||||||
|
|
||||||
|
// Recursively divide front space (toward the viewer).
|
||||||
|
RenderPolyNode(bsp->children[side], subsectorDepth, frontsector);
|
||||||
|
|
||||||
|
// Possibly divide back space (away from the viewer).
|
||||||
|
side ^= 1;
|
||||||
|
|
||||||
|
// Don't bother culling on poly objects
|
||||||
|
//if (!CheckBBox(bsp->bbox[side]))
|
||||||
|
// return;
|
||||||
|
|
||||||
|
node = bsp->children[side];
|
||||||
|
}
|
||||||
|
|
||||||
|
subsector_t *sub = (subsector_t *)((uint8_t *)node - 1);
|
||||||
|
RenderPolySubsector(sub, subsectorDepth, frontsector);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderPolyScene::RenderPolySubsector(subsector_t *sub, uint32_t subsectorDepth, sector_t *frontsector)
|
||||||
|
{
|
||||||
|
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||||
|
{
|
||||||
|
seg_t *line = &sub->firstline[i];
|
||||||
|
if (line->linedef)
|
||||||
|
{
|
||||||
|
// Reject lines not facing viewer
|
||||||
|
DVector2 pt1 = line->v1->fPos() - viewpoint.Pos;
|
||||||
|
DVector2 pt2 = line->v2->fPos() - viewpoint.Pos;
|
||||||
|
if (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Cull wall if not visible
|
||||||
|
angle_t angle1, angle2;
|
||||||
|
if (!Cull.GetAnglesForLine(line->v1->fX(), line->v1->fY(), line->v2->fX(), line->v2->fY(), angle1, angle2))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Tell automap we saw this
|
||||||
|
if (!PolyRenderer::Instance()->DontMapLines && line->linedef)
|
||||||
|
{
|
||||||
|
line->linedef->flags |= ML_MAPPED;
|
||||||
|
sub->flags |= SSECF_DRAWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render wall, and update culling info if its an occlusion blocker
|
||||||
|
if (RenderPolyWall::RenderLine(WorldToClip, PortalPlane, Cull, line, frontsector, subsectorDepth, StencilValue, TranslucentObjects, LinePortals))
|
||||||
|
{
|
||||||
|
Cull.MarkSegmentCulled(angle1, angle2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int RenderPolyScene::PointOnSide(const DVector2 &pos, const node_t *node)
|
||||||
|
{
|
||||||
|
return DMulScale32(FLOAT2FIXED(pos.Y) - node->y, node->dx, node->x - FLOAT2FIXED(pos.X), node->dy) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
void RenderPolyScene::RenderSprite(AActor *thing, double sortDistance, const DVector2 &left, const DVector2 &right)
|
void RenderPolyScene::RenderSprite(AActor *thing, double sortDistance, const DVector2 &left, const DVector2 &right)
|
||||||
{
|
{
|
||||||
if (level.nodes.Size() == 0)
|
if (level.nodes.Size() == 0)
|
||||||
|
|
|
@ -89,6 +89,10 @@ private:
|
||||||
void RenderSprite(AActor *thing, double sortDistance, const DVector2 &left, const DVector2 &right);
|
void RenderSprite(AActor *thing, double sortDistance, const DVector2 &left, const DVector2 &right);
|
||||||
void RenderSprite(AActor *thing, double sortDistance, DVector2 left, DVector2 right, double t1, double t2, void *node);
|
void RenderSprite(AActor *thing, double sortDistance, DVector2 left, DVector2 right, double t1, double t2, void *node);
|
||||||
|
|
||||||
|
void RenderPolySubsector(subsector_t *sub, uint32_t subsectorDepth, sector_t *frontsector);
|
||||||
|
void RenderPolyNode(void *node, uint32_t subsectorDepth, sector_t *frontsector);
|
||||||
|
static int PointOnSide(const DVector2 &pos, const node_t *node);
|
||||||
|
|
||||||
TriMatrix WorldToClip;
|
TriMatrix WorldToClip;
|
||||||
PolyClipPlane PortalPlane;
|
PolyClipPlane PortalPlane;
|
||||||
uint32_t StencilValue = 0;
|
uint32_t StencilValue = 0;
|
||||||
|
|
|
@ -61,7 +61,7 @@ void PolySkyDome::Render(const TriMatrix &worldToClip)
|
||||||
|
|
||||||
float scaleFrontU = frameSetup.frontcyl / (float)frameSetup.frontskytex->GetWidth();
|
float scaleFrontU = frameSetup.frontcyl / (float)frameSetup.frontskytex->GetWidth();
|
||||||
float scaleFrontV = (float)frameSetup.frontskytex->Scale.Y * scaleBaseV;
|
float scaleFrontV = (float)frameSetup.frontskytex->Scale.Y * scaleBaseV;
|
||||||
float offsetFrontU = (float)(frameSetup.frontpos / 65536.0 / frameSetup.frontskytex->GetWidth());
|
float offsetFrontU = (float)((frameSetup.frontpos / 65536.0 + frameSetup.frontcyl / 2) / frameSetup.frontskytex->GetWidth());
|
||||||
float offsetFrontV = (float)((frameSetup.skymid / frameSetup.frontskytex->GetHeight() + offsetBaseV) * scaleBaseV);
|
float offsetFrontV = (float)((frameSetup.skymid / frameSetup.frontskytex->GetHeight() + offsetBaseV) * scaleBaseV);
|
||||||
|
|
||||||
unsigned int count = mVertices.Size();
|
unsigned int count = mVertices.Size();
|
||||||
|
|
|
@ -285,6 +285,8 @@ class OpenALSoundStream : public SoundStream
|
||||||
}
|
}
|
||||||
if(Renderer->AL.EXT_SOURCE_RADIUS)
|
if(Renderer->AL.EXT_SOURCE_RADIUS)
|
||||||
alSourcef(Source, AL_SOURCE_RADIUS, 0.f);
|
alSourcef(Source, AL_SOURCE_RADIUS, 0.f);
|
||||||
|
if(Renderer->AL.SOFT_source_spatialize)
|
||||||
|
alSourcei(Source, AL_SOURCE_SPATIALIZE_SOFT, AL_AUTO_SOFT);
|
||||||
|
|
||||||
alGenBuffers(BufferCount, Buffers);
|
alGenBuffers(BufferCount, Buffers);
|
||||||
return (getALError() == AL_NO_ERROR);
|
return (getALError() == AL_NO_ERROR);
|
||||||
|
@ -816,6 +818,7 @@ OpenALSoundRenderer::OpenALSoundRenderer()
|
||||||
AL.SOFT_deferred_updates = !!alIsExtensionPresent("AL_SOFT_deferred_updates");
|
AL.SOFT_deferred_updates = !!alIsExtensionPresent("AL_SOFT_deferred_updates");
|
||||||
AL.SOFT_loop_points = !!alIsExtensionPresent("AL_SOFT_loop_points");
|
AL.SOFT_loop_points = !!alIsExtensionPresent("AL_SOFT_loop_points");
|
||||||
AL.SOFT_source_resampler = !!alIsExtensionPresent("AL_SOFT_source_resampler");
|
AL.SOFT_source_resampler = !!alIsExtensionPresent("AL_SOFT_source_resampler");
|
||||||
|
AL.SOFT_source_spatialize = !!alIsExtensionPresent("AL_SOFT_source_spatialize");
|
||||||
|
|
||||||
alDopplerFactor(0.5f);
|
alDopplerFactor(0.5f);
|
||||||
alSpeedOfSound(343.3f * 96.0f);
|
alSpeedOfSound(343.3f * 96.0f);
|
||||||
|
@ -1177,6 +1180,9 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSoundRaw(uint8_t *sfxdata,
|
||||||
|
|
||||||
if(length == 0) return std::make_pair(retval, true);
|
if(length == 0) return std::make_pair(retval, true);
|
||||||
|
|
||||||
|
/* Only downmix to mono if we can't spatialize multi-channel sounds. */
|
||||||
|
monoize = monoize && !AL.SOFT_source_spatialize;
|
||||||
|
|
||||||
if(bits == -8)
|
if(bits == -8)
|
||||||
{
|
{
|
||||||
// Simple signed->unsigned conversion
|
// Simple signed->unsigned conversion
|
||||||
|
@ -1264,7 +1270,7 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSoundRaw(uint8_t *sfxdata,
|
||||||
}
|
}
|
||||||
|
|
||||||
retval.data = MAKE_PTRID(buffer);
|
retval.data = MAKE_PTRID(buffer);
|
||||||
return std::make_pair(retval, channels==1);
|
return std::make_pair(retval, AL.SOFT_source_spatialize || channels==1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FindLoopTags(FileReader *fr, uint32_t *start, bool *startass, uint32_t *end, bool *endass);
|
void FindLoopTags(FileReader *fr, uint32_t *start, bool *startass, uint32_t *end, bool *endass);
|
||||||
|
@ -1280,6 +1286,9 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int
|
||||||
uint32_t loop_start = 0, loop_end = ~0u;
|
uint32_t loop_start = 0, loop_end = ~0u;
|
||||||
bool startass = false, endass = false;
|
bool startass = false, endass = false;
|
||||||
|
|
||||||
|
/* Only downmix to mono if we can't spatialize multi-channel sounds. */
|
||||||
|
monoize = monoize && !AL.SOFT_source_spatialize;
|
||||||
|
|
||||||
if (!memcmp(sfxdata, "OggS", 4) || !memcmp(sfxdata, "FLAC", 4))
|
if (!memcmp(sfxdata, "OggS", 4) || !memcmp(sfxdata, "FLAC", 4))
|
||||||
{
|
{
|
||||||
MemoryReader mr((char*)sfxdata, length);
|
MemoryReader mr((char*)sfxdata, length);
|
||||||
|
@ -1377,7 +1386,7 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int
|
||||||
pBuffer->type = type;
|
pBuffer->type = type;
|
||||||
pBuffer->srate = srate;
|
pBuffer->srate = srate;
|
||||||
}
|
}
|
||||||
return std::make_pair(retval, (chans == ChannelConfig_Mono || monoize));
|
return std::make_pair(retval, AL.SOFT_source_spatialize || chans == ChannelConfig_Mono || monoize);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<SoundHandle, bool> OpenALSoundRenderer::LoadSoundBuffered(FSoundLoadBuffer *pBuffer, bool monoize)
|
std::pair<SoundHandle, bool> OpenALSoundRenderer::LoadSoundBuffered(FSoundLoadBuffer *pBuffer, bool monoize)
|
||||||
|
@ -1389,6 +1398,9 @@ std::pair<SoundHandle, bool> OpenALSoundRenderer::LoadSoundBuffered(FSoundLoadBu
|
||||||
auto chans = pBuffer->chans;
|
auto chans = pBuffer->chans;
|
||||||
uint32_t loop_start = pBuffer->loop_start, loop_end = pBuffer->loop_end;
|
uint32_t loop_start = pBuffer->loop_start, loop_end = pBuffer->loop_end;
|
||||||
|
|
||||||
|
/* Only downmix to mono if we can't spatialize multi-channel sounds. */
|
||||||
|
monoize = monoize && !AL.SOFT_source_spatialize;
|
||||||
|
|
||||||
if (chans == ChannelConfig_Mono || monoize)
|
if (chans == ChannelConfig_Mono || monoize)
|
||||||
{
|
{
|
||||||
if (type == SampleType_UInt8) format = AL_FORMAT_MONO8;
|
if (type == SampleType_UInt8) format = AL_FORMAT_MONO8;
|
||||||
|
@ -1461,7 +1473,7 @@ std::pair<SoundHandle, bool> OpenALSoundRenderer::LoadSoundBuffered(FSoundLoadBu
|
||||||
}
|
}
|
||||||
|
|
||||||
retval.data = MAKE_PTRID(buffer);
|
retval.data = MAKE_PTRID(buffer);
|
||||||
return std::make_pair(retval, (chans == ChannelConfig_Mono || monoize));
|
return std::make_pair(retval, AL.SOFT_source_spatialize || chans == ChannelConfig_Mono || monoize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenALSoundRenderer::UnloadSound(SoundHandle sfx)
|
void OpenALSoundRenderer::UnloadSound(SoundHandle sfx)
|
||||||
|
@ -1560,6 +1572,8 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int
|
||||||
alSourcef(source, AL_GAIN, SfxVolume*vol);
|
alSourcef(source, AL_GAIN, SfxVolume*vol);
|
||||||
if(AL.EXT_SOURCE_RADIUS)
|
if(AL.EXT_SOURCE_RADIUS)
|
||||||
alSourcef(source, AL_SOURCE_RADIUS, 0.f);
|
alSourcef(source, AL_SOURCE_RADIUS, 0.f);
|
||||||
|
if(AL.SOFT_source_spatialize)
|
||||||
|
alSourcei(source, AL_SOURCE_SPATIALIZE_SOFT, AL_AUTO_SOFT);
|
||||||
|
|
||||||
if(EnvSlot)
|
if(EnvSlot)
|
||||||
{
|
{
|
||||||
|
@ -1768,6 +1782,8 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
||||||
|
|
||||||
alSourcef(source, AL_MAX_GAIN, SfxVolume);
|
alSourcef(source, AL_MAX_GAIN, SfxVolume);
|
||||||
alSourcef(source, AL_GAIN, SfxVolume*vol);
|
alSourcef(source, AL_GAIN, SfxVolume*vol);
|
||||||
|
if(AL.SOFT_source_spatialize)
|
||||||
|
alSourcei(source, AL_SOURCE_SPATIALIZE_SOFT, AL_TRUE);
|
||||||
|
|
||||||
if(EnvSlot)
|
if(EnvSlot)
|
||||||
{
|
{
|
||||||
|
|
|
@ -109,6 +109,12 @@ AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef AL_SOFT_source_spatialize
|
||||||
|
#define AL_SOFT_source_spatialize
|
||||||
|
#define AL_SOURCE_SPATIALIZE_SOFT 0x1214
|
||||||
|
#define AL_AUTO_SOFT 0x0002
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class OpenALSoundStream;
|
class OpenALSoundStream;
|
||||||
|
|
||||||
|
@ -184,6 +190,7 @@ private:
|
||||||
bool SOFT_deferred_updates;
|
bool SOFT_deferred_updates;
|
||||||
bool SOFT_loop_points;
|
bool SOFT_loop_points;
|
||||||
bool SOFT_source_resampler;
|
bool SOFT_source_resampler;
|
||||||
|
bool SOFT_source_spatialize;
|
||||||
} AL;
|
} AL;
|
||||||
|
|
||||||
// EFX Extension function pointer variables. Loaded after context creation
|
// EFX Extension function pointer variables. Loaded after context creation
|
||||||
|
|
|
@ -395,17 +395,22 @@ IWad
|
||||||
Names
|
Names
|
||||||
{
|
{
|
||||||
"doom_complete.pk3"
|
"doom_complete.pk3"
|
||||||
"bfgdoom2.wad"
|
|
||||||
"doom2bfg.wad"
|
|
||||||
"doom2f.wad"
|
|
||||||
"doom2.wad"
|
"doom2.wad"
|
||||||
"plutonia.wad"
|
"plutonia.wad"
|
||||||
"tnt.wad"
|
"tnt.wad"
|
||||||
"bfgdoom.wad"
|
|
||||||
"doombfg.wad"
|
|
||||||
"doomu.wad"
|
"doomu.wad"
|
||||||
"doom.wad"
|
"doom.wad"
|
||||||
"doom1.wad"
|
"doom1.wad"
|
||||||
|
"bfgdoom2.wad"
|
||||||
|
"doom2bfg.wad"
|
||||||
|
"bfgdoom.wad"
|
||||||
|
"doombfg.wad"
|
||||||
|
"doom2f.wad"
|
||||||
|
"freedoom1.wad"
|
||||||
|
"freedoom2.wad"
|
||||||
|
"freedoomu.wad"
|
||||||
|
"freedoom.wad"
|
||||||
|
"freedm.wad"
|
||||||
"heretic.wad"
|
"heretic.wad"
|
||||||
"hereticsr.wad"
|
"hereticsr.wad"
|
||||||
"heretic1.wad"
|
"heretic1.wad"
|
||||||
|
@ -413,15 +418,10 @@ Names
|
||||||
"hexdd.wad"
|
"hexdd.wad"
|
||||||
"hexendemo.wad"
|
"hexendemo.wad"
|
||||||
"hexdemo.wad"
|
"hexdemo.wad"
|
||||||
"sve.wad"
|
|
||||||
"strife1.wad"
|
"strife1.wad"
|
||||||
|
"sve.wad"
|
||||||
"strife0.wad"
|
"strife0.wad"
|
||||||
"strife.wad"
|
"strife.wad"
|
||||||
"freedoom1.wad"
|
|
||||||
"freedoom2.wad"
|
|
||||||
"freedoomu.wad"
|
|
||||||
"freedoom.wad"
|
|
||||||
"freedm.wad"
|
|
||||||
"blasphem.wad"
|
"blasphem.wad"
|
||||||
"blasphemer.wad"
|
"blasphemer.wad"
|
||||||
"chex.wad"
|
"chex.wad"
|
||||||
|
|
Loading…
Reference in a new issue