diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5086256eb66..8a9ed3a537c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -856,9 +856,9 @@ set( FASTMATH_SOURCES gl/scene/gl_walls_draw.cpp gl/scene/gl_vertex.cpp gl/scene/gl_spritelight.cpp - gl/dynlights/gl_dynlight1.cpp gl_load/gl_load.c gl/models/gl_models.cpp + hwrenderer/dynlights/hw_dynlightdata.cpp r_data/models/models.cpp r_data/matrix.cpp sound/adlmidi/adldata.cpp diff --git a/src/compatibility.cpp b/src/compatibility.cpp index 74b0354d8ae..40d7bfbe201 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -74,28 +74,6 @@ enum SLOT_BCOMPAT }; -enum -{ - CP_END, - CP_CLEARFLAGS, - CP_SETFLAGS, - CP_SETSPECIAL, - CP_CLEARSPECIAL, - CP_SETACTIVATION, - CP_SETSECTOROFFSET, - CP_SETSECTORSPECIAL, - CP_SETWALLYSCALE, - CP_SETWALLTEXTURE, - CP_SETTHINGZ, - CP_SETTAG, - CP_SETTHINGFLAGS, - CP_SETVERTEX, - CP_SETTHINGSKILLS, - CP_SETSECTORTEXTURE, - CP_SETSECTORLIGHT, - CP_SETLINESECTORREF, -}; - // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- @@ -397,6 +375,22 @@ DEFINE_ACTION_FUNCTION(DLevelCompatibility, SetThingSkills) return 0; } +DEFINE_ACTION_FUNCTION(DLevelCompatibility, SetThingXY) +{ + PARAM_PROLOGUE; + PARAM_INT(thing); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + + if ((unsigned)thing < MapThingsConverted.Size()) + { + auto& pos = MapThingsConverted[thing].pos; + pos.X = x; + pos.Y = y; + } + return 0; +} + DEFINE_ACTION_FUNCTION(DLevelCompatibility, SetThingZ) { PARAM_PROLOGUE; diff --git a/src/g_shared/a_dynlight.h b/src/g_shared/a_dynlight.h index adfaa3a4f04..1498b85eb51 100644 --- a/src/g_shared/a_dynlight.h +++ b/src/g_shared/a_dynlight.h @@ -229,5 +229,7 @@ class ADynamicLight : public AActor LightFlags lightflags; DAngle SpotInnerAngle = 10.0; DAngle SpotOuterAngle = 25.0; + + int mShadowmapIndex = 1024; }; diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 7933503a8ba..e849adfd2f2 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -658,7 +658,6 @@ void DBaseStatusBar::AttachMessage (DHUDMessageBase *msg, uint32_t id, int layer { DHUDMessageBase *old = NULL; DHUDMessageBase **prev; - DObject *container = this; old = (id == 0 || id == 0xFFFFFFFF) ? NULL : DetachMessage (id); if (old != NULL) @@ -679,14 +678,13 @@ void DBaseStatusBar::AttachMessage (DHUDMessageBase *msg, uint32_t id, int layer // it gets drawn back to front.) while (*prev != NULL && (*prev)->SBarID > id) { - container = *prev; prev = &(*prev)->Next; } msg->Next = *prev; msg->SBarID = id; *prev = msg; - GC::WriteBarrier(container, msg); + GC::WriteBarrier(msg); } DEFINE_ACTION_FUNCTION(DBaseStatusBar, AttachMessage) diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index ea32d58c27a..39e9578771e 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -40,7 +40,8 @@ #include "g_levellocals.h" #include "actorinlines.h" #include "g_levellocals.h" -#include "gl/dynlights/gl_dynlight.h" +#include "hwrenderer/dynlights/hw_dynlightdata.h" + #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_lightdata.h" #include "gl/system/gl_interface.h" @@ -438,7 +439,7 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, FVector3 & nearP if (radius <= 0.f) return false; if (dist > radius) return false; - if (checkside && gl_lights_checkside && p.PointOnSide(lpos.X, lpos.Z, lpos.Y)) + if (checkside && p.PointOnSide(lpos.X, lpos.Z, lpos.Y)) { return false; } @@ -559,7 +560,8 @@ bool FDrawInfo::PutWallCompat(GLWall *wall, int passflag) bool masked = passflag == 2 && wall->gltexture->isMasked(); int list = list_indices[masked][foggy]; - dldrawlists[list].AddWall(wall); + auto newwall = dldrawlists[list].NewWall(); + *newwall = *wall; return true; } @@ -583,7 +585,8 @@ bool GLFlat::PutFlatCompat(bool fog) int list = list_indices[masked][foggy]; - gl_drawinfo->dldrawlists[list].AddFlat(this); + auto newflat = gl_drawinfo->dldrawlists[list].NewFlat(); + *newflat = *this; return true; } @@ -664,7 +667,7 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass) // we must do the side check here because gl_SetupLight needs the correct plane orientation // which we don't have for Legacy-style 3D-floors double planeh = plane.plane.ZatPoint(light); - if (gl_lights_checkside && ((planehZ() && ceiling) || (planeh>light->Z() && !ceiling))) + if (((planehZ() && ceiling) || (planeh>light->Z() && !ceiling))) { node = node->nextLight; continue; @@ -745,7 +748,7 @@ bool GLWall::PrepareLight(ADynamicLight * light, int pass) float scale; auto normal = glseg.Normal(); - p.Set(normal, -normal.X * glseg.x1 - normal.Y * glseg.y1); + p.Set(normal, -normal.X * glseg.x1 - normal.Z * glseg.y1); if (!p.ValidNormal()) { @@ -1001,4 +1004,4 @@ int LegacyDesaturation(F2DDrawer::RenderCommand &cmd) auto &tbl = DesaturatedTranslationTable[cmd.mTranslation]; tbl.tables[desat] = newremap; return newremap->GetUniqueIndex(); -} \ No newline at end of file +} diff --git a/src/gl/compatibility/gl_swshader20.cpp b/src/gl/compatibility/gl_swshader20.cpp index 334a09612c7..17adec972c3 100644 --- a/src/gl/compatibility/gl_swshader20.cpp +++ b/src/gl/compatibility/gl_swshader20.cpp @@ -34,7 +34,8 @@ #include "i_system.h" #include "r_utility.h" #include "w_wad.h" -#include "gl/dynlights/gl_dynlight.h" +#include "hwrenderer/dynlights/hw_dynlightdata.h" + #include "gl/renderer/gl_renderer.h" #include "gl/system/gl_interface.h" #include "gl/renderer/gl_renderstate.h" diff --git a/src/gl/dynlights/gl_lightbuffer.cpp b/src/gl/dynlights/gl_lightbuffer.cpp index aa37ea16798..56009798738 100644 --- a/src/gl/dynlights/gl_lightbuffer.cpp +++ b/src/gl/dynlights/gl_lightbuffer.cpp @@ -28,9 +28,9 @@ #include "gl/system/gl_system.h" #include "gl/shaders/gl_shader.h" #include "gl/dynlights/gl_lightbuffer.h" -#include "gl/dynlights/gl_dynlight.h" #include "gl/system/gl_interface.h" #include "gl/utility//gl_clock.h" +#include "hwrenderer/dynlights/hw_dynlightdata.h" static const int INITIAL_BUFFER_SIZE = 160000; // This means 80000 lights per frame and 160000*16 bytes == 2.56 MB. diff --git a/src/gl/dynlights/gl_shadowmap.cpp b/src/gl/dynlights/gl_shadowmap.cpp index 9e6ee4c917a..0d8f9ebbef6 100644 --- a/src/gl/dynlights/gl_shadowmap.cpp +++ b/src/gl/dynlights/gl_shadowmap.cpp @@ -23,7 +23,6 @@ #include "gl/system/gl_system.h" #include "gl/shaders/gl_shader.h" #include "gl/dynlights/gl_shadowmap.h" -#include "gl/dynlights/gl_dynlight.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_debug.h" #include "gl/system/gl_cvars.h" @@ -31,6 +30,7 @@ #include "gl/renderer/gl_postprocessstate.h" #include "gl/renderer/gl_renderbuffers.h" #include "gl/shaders/gl_shadowmapshader.h" +#include "hwrenderer/dynlights/hw_dynlightdata.h" #include "r_state.h" #include "g_levellocals.h" #include "stats.h" @@ -42,12 +42,7 @@ the fragment shader (main.fp) needs to sample from row 20. That is, the V texture coordinate needs to be 20.5/1024. - mLightToShadowmap is a hash map storing which line each ADynamicLight is assigned to. The public - ShadowMapIndex function allows the main rendering to find the index and upload that along with the - normal light data. From there, the main.fp shader can sample from the shadow map texture, which - is currently always bound to texture unit 16. - - The texel row for each light is split into four parts. One for each direction, like a cube texture, + The texel row for each light is split into four parts. One for each direction, like a cube texture, but then only in 2D where this reduces itself to a square. When main.fp samples from the shadow map it first decides in which direction the fragment is (relative to the light), like cubemap sampling does for 3D, but once again just for the 2D case. @@ -97,6 +92,20 @@ CUSTOM_CVAR(Int, gl_shadowmap_quality, 512, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) } } +CUSTOM_CVAR (Bool, gl_light_shadowmap, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (!self) + { + // Unset any residual shadow map indices in the light actors. + TThinkerIterator it(STAT_DLIGHT); + while (auto light = it.Next()) + { + light->mShadowmapIndex = 1024; + } + } +} + + void FShadowMap::Update() { UpdateCycles.Reset(); @@ -152,42 +161,32 @@ bool FShadowMap::IsEnabled() const return gl_light_shadowmap && !!(gl.flags & RFL_SHADER_STORAGE_BUFFER); } -int FShadowMap::ShadowMapIndex(ADynamicLight *light) -{ - if (IsEnabled()) - { - auto val = mLightToShadowmap.CheckKey(light); - if (val != nullptr) return *val; - } - return 1024; -} - void FShadowMap::UploadLights() { if (mLights.Size() != 1024 * 4) mLights.Resize(1024 * 4); int lightindex = 0; - mLightToShadowmap.Clear(mLightToShadowmap.CountUsed() * 2); // To do: allow clearing a TMap while building up a reserve // Todo: this should go through the blockmap in a spiral pattern around the player so that closer lights are preferred. TThinkerIterator it(STAT_DLIGHT); while (auto light = it.Next()) { LightsProcessed++; - if (light->shadowmapped) + if (light->shadowmapped && lightindex < 1024 * 4) { LightsShadowmapped++; - mLightToShadowmap[light] = lightindex >> 2; + light->mShadowmapIndex = lightindex >> 2; mLights[lightindex] = light->X(); mLights[lightindex+1] = light->Y(); mLights[lightindex+2] = light->Z(); mLights[lightindex+3] = light->GetRadius(); lightindex += 4; - - if (lightindex == 1024*4) // Only 1024 lights for now - break; } + else + { + light->mShadowmapIndex = 1024; + } } diff --git a/src/gl/dynlights/gl_shadowmap.h b/src/gl/dynlights/gl_shadowmap.h index eea0c9f4aac..d2081ff2a37 100644 --- a/src/gl/dynlights/gl_shadowmap.h +++ b/src/gl/dynlights/gl_shadowmap.h @@ -20,9 +20,6 @@ class FShadowMap // Update shadow map texture void Update(); - // Return the assigned shadow map index for a given light - int ShadowMapIndex(ADynamicLight *light); - // Test if a world position is in shadow relative to the specified light and returns false if it is bool ShadowTest(ADynamicLight *light, const DVector3 &pos); @@ -42,9 +39,6 @@ class FShadowMap // Working buffer for creating the list of lights. Stored here to avoid allocating memory each frame TArray mLights; - // The assigned shadow map index for each light - TMap mLightToShadowmap; - // OpenGL storage buffers for the AABB tree int mNodesBuffer = 0; int mLinesBuffer = 0; diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 2d02742f650..a24210678e9 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -69,7 +69,6 @@ void FRenderState::Reset() currentColorMask[0] = currentColorMask[1] = currentColorMask[2] = currentColorMask[3] = true; mFogColor.d = -1; mTextureMode = -1; - mLightIndex = -1; mDesaturation = 0; mSrcBlend = GL_SRC_ALPHA; mDstBlend = GL_ONE_MINUS_SRC_ALPHA; @@ -176,7 +175,7 @@ bool FRenderState::ApplyShader() activeShader->muClipHeightDirection.Set(mClipHeightDirection); activeShader->muTimer.Set((double)(screen->FrameTime - firstFrame) * (double)mShaderTimer / 1000.); activeShader->muAlphaThreshold.Set(mAlphaThreshold); - activeShader->muLightIndex.Set(mLightIndex); // will always be -1 for now + activeShader->muLightIndex.Set(-1); activeShader->muClipSplit.Set(mClipSplit); activeShader->muViewHeight.Set(viewheight); activeShader->muSpecularMaterial.Set(mGlossiness, mSpecularLevel); diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 54590e9deb6..8c69ff4c7b3 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -82,7 +82,6 @@ class FRenderState bool mBrightmapEnabled; bool mColorMask[4]; bool currentColorMask[4]; - int mLightIndex; int mSpecialEffect; int mTextureMode; int mDesaturation; @@ -327,11 +326,6 @@ class FRenderState } } - void SetLightIndex(int n) - { - mLightIndex = n; - } - void EnableBrightmap(bool on) { mBrightmapEnabled = on; diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 91e11c3280c..d87166361be 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -33,6 +33,7 @@ #include "r_state.h" #include "doomstat.h" #include "g_levellocals.h" +#include "memarena.h" #include "gl/system/gl_cvars.h" #include "gl/data/gl_vertexbuffer.h" @@ -50,6 +51,13 @@ FDrawInfo * gl_drawinfo; FDrawInfoList di_list; +static FMemArena RenderDataAllocator(1024*1024); // Use large blocks to reduce allocation time. + +void ResetAllocator() +{ + RenderDataAllocator.FreeAll(); +} + //========================================================================== // // @@ -244,7 +252,7 @@ SortNode * GLDrawList::FindSortWall(SortNode * head) GLDrawItem * it = &drawitems[node->itemindex]; if (it->rendertype == GLDIT_WALL) { - float d = walls[it->index].ViewDistance; + float d = walls[it->index]->ViewDistance; if (d > farthest) farthest = d; if (d < nearest) nearest = d; } @@ -258,7 +266,7 @@ SortNode * GLDrawList::FindSortWall(SortNode * head) GLDrawItem * it = &drawitems[node->itemindex]; if (it->rendertype == GLDIT_WALL) { - float di = fabsf(walls[it->index].ViewDistance - farthest); + float di = fabsf(walls[it->index]->ViewDistance - farthest); if (!best || di < bestdist) { best = node; @@ -277,8 +285,8 @@ SortNode * GLDrawList::FindSortWall(SortNode * head) //========================================================================== void GLDrawList::SortPlaneIntoPlane(SortNode * head,SortNode * sort) { - GLFlat * fh=&flats[drawitems[head->itemindex].index]; - GLFlat * fs=&flats[drawitems[sort->itemindex].index]; + GLFlat * fh= flats[drawitems[head->itemindex].index]; + GLFlat * fs= flats[drawitems[sort->itemindex].index]; if (fh->z==fs->z) head->AddToEqual(sort); @@ -294,10 +302,10 @@ void GLDrawList::SortPlaneIntoPlane(SortNode * head,SortNode * sort) // // //========================================================================== -void GLDrawList::SortWallIntoPlane(SortNode * head,SortNode * sort) +void GLDrawList::SortWallIntoPlane(SortNode * head, SortNode * sort) { - GLFlat * fh=&flats[drawitems[head->itemindex].index]; - GLWall * ws=&walls[drawitems[sort->itemindex].index]; + GLFlat * fh = flats[drawitems[head->itemindex].index]; + GLWall * ws = walls[drawitems[sort->itemindex].index]; bool ceiling = fh->z > r_viewpoint.Pos.Z; @@ -305,18 +313,13 @@ void GLDrawList::SortWallIntoPlane(SortNode * head,SortNode * sort) { // We have to split this wall! - // WARNING: NEVER EVER push a member of an array onto the array itself. - // Bad things will happen if the memory must be reallocated! - GLWall w = *ws; - AddWall(&w); - + GLWall *w = NewWall(); + *w = *ws; + // Splitting is done in the shader with clip planes, if available if (gl.flags & RFL_NO_CLIP_PLANES) { - GLWall * ws1; ws->vertcount = 0; // invalidate current vertices. - ws1=&walls[walls.Size()-1]; - ws=&walls[drawitems[sort->itemindex].index]; // may have been reallocated! float newtexv = ws->tcs[GLWall::UPLFT].v + ((ws->tcs[GLWall::LOLFT].v - ws->tcs[GLWall::UPLFT].v) / (ws->zbottom[0] - ws->ztop[0])) * (fh->z - ws->ztop[0]); // I make the very big assumption here that translucent walls in sloped sectors @@ -324,13 +327,13 @@ void GLDrawList::SortWallIntoPlane(SortNode * head,SortNode * sort) // code would become extremely more complicated. if (!ceiling) { - ws->ztop[1] = ws1->zbottom[1] = ws->ztop[0] = ws1->zbottom[0] = fh->z; - ws->tcs[GLWall::UPRGT].v = ws1->tcs[GLWall::LORGT].v = ws->tcs[GLWall::UPLFT].v = ws1->tcs[GLWall::LOLFT].v = newtexv; + ws->ztop[1] = w->zbottom[1] = ws->ztop[0] = w->zbottom[0] = fh->z; + ws->tcs[GLWall::UPRGT].v = w->tcs[GLWall::LORGT].v = ws->tcs[GLWall::UPLFT].v = w->tcs[GLWall::LOLFT].v = newtexv; } else { - ws1->ztop[1] = ws->zbottom[1] = ws1->ztop[0] = ws->zbottom[0] = fh->z; - ws1->tcs[GLWall::UPLFT].v = ws->tcs[GLWall::LOLFT].v = ws1->tcs[GLWall::UPRGT].v = ws->tcs[GLWall::LORGT].v=newtexv; + w->ztop[1] = ws->zbottom[1] = w->ztop[0] = ws->zbottom[0] = fh->z; + w->tcs[GLWall::UPLFT].v = ws->tcs[GLWall::LOLFT].v = w->tcs[GLWall::UPRGT].v = ws->tcs[GLWall::LORGT].v = newtexv; } } @@ -341,7 +344,7 @@ void GLDrawList::SortWallIntoPlane(SortNode * head,SortNode * sort) head->AddToLeft(sort); head->AddToRight(sort2); } - else if ((ws->zbottom[0]z && !ceiling) || (ws->ztop[0]>fh->z && ceiling)) // completely on the left side + else if ((ws->zbottom[0] < fh->z && !ceiling) || (ws->ztop[0] > fh->z && ceiling)) // completely on the left side { head->AddToLeft(sort); } @@ -359,8 +362,8 @@ void GLDrawList::SortWallIntoPlane(SortNode * head,SortNode * sort) //========================================================================== void GLDrawList::SortSpriteIntoPlane(SortNode * head, SortNode * sort) { - GLFlat * fh = &flats[drawitems[head->itemindex].index]; - GLSprite * ss = &sprites[drawitems[sort->itemindex].index]; + GLFlat * fh = flats[drawitems[head->itemindex].index]; + GLSprite * ss = sprites[drawitems[sort->itemindex].index]; bool ceiling = fh->z > r_viewpoint.Pos.Z; @@ -370,27 +373,24 @@ void GLDrawList::SortSpriteIntoPlane(SortNode * head, SortNode * sort) if ((hiz > fh->z && loz < fh->z) || ss->modelframe) { // We have to split this sprite - GLSprite s = *ss; - AddSprite(&s); // add a copy to avoid reallocation issues. + GLSprite *s = NewSprite(); + *s = *ss; // Splitting is done in the shader with clip planes, if available. // The fallback here only really works for non-y-billboarded sprites. if (gl.flags & RFL_NO_CLIP_PLANES) { - GLSprite * ss1; - ss1 = &sprites[sprites.Size() - 1]; - ss = &sprites[drawitems[sort->itemindex].index]; // may have been reallocated! float newtexv = ss->vt + ((ss->vb - ss->vt) / (ss->z2 - ss->z1))*(fh->z - ss->z1); if (!ceiling) { - ss->z1 = ss1->z2 = fh->z; - ss->vt = ss1->vb = newtexv; + ss->z1 = s->z2 = fh->z; + ss->vt = s->vb = newtexv; } else { - ss1->z1 = ss->z2 = fh->z; - ss1->vt = ss->vb = newtexv; + s->z1 = ss->z2 = fh->z; + s->vt = ss->vb = newtexv; } } @@ -421,9 +421,8 @@ void GLDrawList::SortSpriteIntoPlane(SortNode * head, SortNode * sort) void GLDrawList::SortWallIntoWall(SortNode * head,SortNode * sort) { - GLWall * wh=&walls[drawitems[head->itemindex].index]; - GLWall * ws=&walls[drawitems[sort->itemindex].index]; - GLWall * ws1; + GLWall * wh= walls[drawitems[head->itemindex].index]; + GLWall * ws= walls[drawitems[sort->itemindex].index]; float v1=wh->PointOnSide(ws->glseg.x1,ws->glseg.y1); float v2=wh->PointOnSide(ws->glseg.x2,ws->glseg.y2); @@ -461,21 +460,19 @@ void GLDrawList::SortWallIntoWall(SortNode * head,SortNode * sort) float izb=(float)(ws->zbottom[0]+r*(ws->zbottom[1]-ws->zbottom[0])); ws->vertcount = 0; // invalidate current vertices. - GLWall w=*ws; - AddWall(&w); - ws1=&walls[walls.Size()-1]; - ws=&walls[drawitems[sort->itemindex].index]; // may have been reallocated! - - ws1->glseg.x1=ws->glseg.x2=ix; - ws1->glseg.y1=ws->glseg.y2=iy; - ws1->glseg.fracleft = ws->glseg.fracright = ws->glseg.fracleft + r*(ws->glseg.fracright - ws->glseg.fracleft); - ws1->ztop[0]=ws->ztop[1]=izt; - ws1->zbottom[0]=ws->zbottom[1]=izb; - ws1->tcs[GLWall::LOLFT].u = ws1->tcs[GLWall::UPLFT].u = ws->tcs[GLWall::LORGT].u = ws->tcs[GLWall::UPRGT].u = iu; + GLWall *w= NewWall(); + *w = *ws; + + w->glseg.x1=ws->glseg.x2=ix; + w->glseg.y1=ws->glseg.y2=iy; + w->glseg.fracleft = ws->glseg.fracright = ws->glseg.fracleft + r*(ws->glseg.fracright - ws->glseg.fracleft); + w->ztop[0]=ws->ztop[1]=izt; + w->zbottom[0]=ws->zbottom[1]=izb; + w->tcs[GLWall::LOLFT].u = w->tcs[GLWall::UPLFT].u = ws->tcs[GLWall::LORGT].u = ws->tcs[GLWall::UPRGT].u = iu; if (gl.buffermethod == BM_DEFERRED) { ws->MakeVertices(false); - ws1->MakeVertices(false); + w->MakeVertices(false); } SortNode * sort2=SortNodes.GetNew(); @@ -507,9 +504,8 @@ EXTERN_CVAR(Bool, gl_billboard_particles) void GLDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort) { - GLWall * wh=&walls[drawitems[head->itemindex].index]; - GLSprite * ss=&sprites[drawitems[sort->itemindex].index]; - GLSprite * ss1; + GLWall *wh= walls[drawitems[head->itemindex].index]; + GLSprite * ss= sprites[drawitems[sort->itemindex].index]; float v1 = wh->PointOnSide(ss->x1, ss->y1); float v2 = wh->PointOnSide(ss->x2, ss->y2); @@ -562,14 +558,12 @@ void GLDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort) float iy=(float)(ss->y1 + r * (ss->y2-ss->y1)); float iu=(float)(ss->ul + r * (ss->ur-ss->ul)); - GLSprite s=*ss; - AddSprite(&s); - ss1=&sprites[sprites.Size()-1]; - ss=&sprites[drawitems[sort->itemindex].index]; // may have been reallocated! + GLSprite *s = NewSprite(); + *s = *ss; - ss1->x1=ss->x2=ix; - ss1->y1=ss->y2=iy; - ss1->ul=ss->ur=iu; + s->x1=ss->x2=ix; + s->y1=ss->y2=iy; + s->ul=ss->ur=iu; SortNode * sort2=SortNodes.GetNew(); memset(sort2,0,sizeof(SortNode)); @@ -597,8 +591,8 @@ void GLDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort) inline int GLDrawList::CompareSprites(SortNode * a,SortNode * b) { - GLSprite * s1=&sprites[drawitems[a->itemindex].index]; - GLSprite * s2=&sprites[drawitems[b->itemindex].index]; + GLSprite * s1= sprites[drawitems[a->itemindex].index]; + GLSprite * s2= sprites[drawitems[b->itemindex].index]; int res = s1->depth - s2->depth; @@ -722,7 +716,7 @@ void GLDrawList::DoDraw(int pass, int i, bool trans) { case GLDIT_FLAT: { - GLFlat * f=&flats[drawitems[i].index]; + GLFlat * f= flats[drawitems[i].index]; RenderFlat.Clock(); f->Draw(pass, trans); RenderFlat.Unclock(); @@ -731,7 +725,7 @@ void GLDrawList::DoDraw(int pass, int i, bool trans) case GLDIT_WALL: { - GLWall * w=&walls[drawitems[i].index]; + GLWall * w= walls[drawitems[i].index]; RenderWall.Clock(); w->Draw(pass); RenderWall.Unclock(); @@ -740,7 +734,7 @@ void GLDrawList::DoDraw(int pass, int i, bool trans) case GLDIT_SPRITE: { - GLSprite * s=&sprites[drawitems[i].index]; + GLSprite * s= sprites[drawitems[i].index]; RenderSprite.Clock(); s->Draw(pass); RenderSprite.Unclock(); @@ -764,7 +758,7 @@ void GLDrawList::DoDrawSorted(SortNode * head) if (drawitems[head->itemindex].rendertype == GLDIT_FLAT) { - z = flats[drawitems[head->itemindex].index].z; + z = flats[drawitems[head->itemindex].index]->z; relation = z > r_viewpoint.Pos.Z ? 1 : -1; } @@ -863,7 +857,7 @@ void GLDrawList::DrawWalls(int pass) RenderWall.Clock(); for(unsigned i=0;iDraw(pass); } RenderWall.Unclock(); } @@ -878,7 +872,7 @@ void GLDrawList::DrawFlats(int pass) RenderFlat.Clock(); for(unsigned i=0;iDraw(pass, false); } RenderFlat.Unclock(); } @@ -892,7 +886,7 @@ void GLDrawList::DrawDecals() { for(unsigned i=0;iDoDrawDecals(); } } @@ -908,8 +902,8 @@ void GLDrawList::SortWalls() { std::sort(drawitems.begin(), drawitems.end(), [=](const GLDrawItem &a, const GLDrawItem &b) -> bool { - GLWall * w1 = &walls[a.index]; - GLWall * w2 = &walls[b.index]; + GLWall * w1 = walls[a.index]; + GLWall * w2 = walls[b.index]; if (w1->gltexture != w2->gltexture) return w1->gltexture < w2->gltexture; return (w1->flags & 3) < (w2->flags & 3); @@ -924,8 +918,8 @@ void GLDrawList::SortFlats() { std::sort(drawitems.begin(), drawitems.end(), [=](const GLDrawItem &a, const GLDrawItem &b) { - GLFlat * w1 = &flats[a.index]; - GLFlat* w2 = &flats[b.index]; + GLFlat * w1 = flats[a.index]; + GLFlat* w2 = flats[b.index]; return w1->gltexture < w2->gltexture; }); } @@ -936,9 +930,12 @@ void GLDrawList::SortFlats() // // //========================================================================== -void GLDrawList::AddWall(GLWall * wall) + +GLWall *GLDrawList::NewWall() { - drawitems.Push(GLDrawItem(GLDIT_WALL,walls.Push(*wall))); + auto wall = (GLWall*)RenderDataAllocator.Alloc(sizeof(GLWall)); + drawitems.Push(GLDrawItem(GLDIT_WALL, walls.Push(wall))); + return wall; } //========================================================================== @@ -946,9 +943,11 @@ void GLDrawList::AddWall(GLWall * wall) // // //========================================================================== -void GLDrawList::AddFlat(GLFlat * flat) +GLFlat *GLDrawList::NewFlat() { - drawitems.Push(GLDrawItem(GLDIT_FLAT,flats.Push(*flat))); + auto flat = (GLFlat*)RenderDataAllocator.Alloc(sizeof(GLFlat)); + drawitems.Push(GLDrawItem(GLDIT_FLAT,flats.Push(flat))); + return flat; } //========================================================================== @@ -956,9 +955,11 @@ void GLDrawList::AddFlat(GLFlat * flat) // // //========================================================================== -void GLDrawList::AddSprite(GLSprite * sprite) +GLSprite *GLDrawList::NewSprite() { - drawitems.Push(GLDrawItem(GLDIT_SPRITE,sprites.Push(*sprite))); + auto sprite = (GLSprite*)RenderDataAllocator.Alloc(sizeof(GLSprite)); + drawitems.Push(GLDrawItem(GLDIT_SPRITE, sprites.Push(sprite))); + return sprite; } @@ -1059,6 +1060,8 @@ void FDrawInfo::EndDrawInfo() } gl_drawinfo=di->next; di_list.Release(di); + if (gl_drawinfo == nullptr) + ResetAllocator(); } diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index 0c2607632fa..0a1ebf35fb4 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -106,9 +106,9 @@ struct SortNode struct GLDrawList { //private: - TArray walls; - TArray flats; - TArray sprites; + TArray walls; + TArray flats; + TArray sprites; TArray drawitems; int SortNodeStart; SortNode * sorted; @@ -131,9 +131,9 @@ struct GLDrawList return drawitems.Size(); } - void AddWall(GLWall * wall); - void AddFlat(GLFlat * flat); - void AddSprite(GLSprite * sprite); + GLWall *NewWall(); + GLFlat *NewFlat(); + GLSprite *NewSprite(); void Reset(); void SortWalls(); void SortFlats(); diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index a3fe05c10dc..888cc189bf1 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -37,6 +37,7 @@ #include "templates.h" #include "g_levellocals.h" #include "actorinlines.h" +#include "hwrenderer/dynlights/hw_dynlightdata.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_cvars.h" @@ -44,7 +45,6 @@ #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" #include "gl/data/gl_vertexbuffer.h" -#include "gl/dynlights/gl_dynlight.h" #include "gl/dynlights/gl_lightbuffer.h" #include "gl/scene/gl_drawinfo.h" #include "gl/shaders/gl_shader.h" @@ -130,17 +130,17 @@ void GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, int *dli) } iter_dlightf++; - // we must do the side check here because gl_SetupLight needs the correct plane orientation + // we must do the side check here because gl_GetLight needs the correct plane orientation // which we don't have for Legacy-style 3D-floors double planeh = plane.plane.ZatPoint(light); - if (gl_lights_checkside && ((planehZ() && ceiling) || (planeh>light->Z() && !ceiling))) + if ((planehZ() && ceiling) || (planeh>light->Z() && !ceiling)) { node = node->nextLight; continue; } p.Set(plane.plane.Normal(), plane.plane.fD()); - gl_GetLight(sub->sector->PortalGroup, p, light, false, lightdata); + lightdata.GetLight(sub->sector->PortalGroup, p, light, false); node = node->nextLight; } @@ -489,7 +489,8 @@ inline void GLFlat::PutFlat(bool fog) list = masked ? GLDL_MASKEDFLATS : GLDL_PLAINFLATS; } dynlightindex = -1; // make sure this is always initialized to something proper. - gl_drawinfo->drawlists[list].AddFlat (this); + auto newflat = gl_drawinfo->drawlists[list].NewFlat(); + *newflat = *this; } //========================================================================== diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 1d3524f753f..1b1f1d28b3f 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -45,6 +45,7 @@ #include "serializer.h" #include "g_levellocals.h" #include "events.h" +#include "hwrenderer/dynlights/hw_dynlightdata.h" #include "gl/dynlights/gl_lightbuffer.h" #include "gl/system/gl_interface.h" @@ -54,8 +55,6 @@ #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_renderbuffers.h" #include "gl/data/gl_vertexbuffer.h" -#include "gl/dynlights/gl_dynlight.h" -#include "gl/models/gl_models.h" #include "gl/scene/gl_clipper.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 939a109f7ce..d4188f3a0c0 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -523,7 +523,8 @@ inline void GLSprite::PutSprite(bool translucent) { list = GLDL_MODELS; } - gl_drawinfo->drawlists[list].AddSprite(this); + auto newsprt = gl_drawinfo->drawlists[list].NewSprite(); + *newsprt = *this; } //========================================================================== diff --git a/src/gl/scene/gl_spritelight.cpp b/src/gl/scene/gl_spritelight.cpp index d25339b9469..d037cd72823 100644 --- a/src/gl/scene/gl_spritelight.cpp +++ b/src/gl/scene/gl_spritelight.cpp @@ -33,11 +33,11 @@ #include "g_level.h" #include "g_levellocals.h" #include "actorinlines.h" +#include "hwrenderer/dynlights/hw_dynlightdata.h" #include "gl/system/gl_cvars.h" #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_lightdata.h" -#include "gl/dynlights/gl_dynlight.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" #include "gl/shaders/gl_shader.h" @@ -243,7 +243,7 @@ int gl_SetDynModelLight(AActor *self, int dynlightindex) { if (std::find(addedLights.begin(), addedLights.end(), light) == addedLights.end()) // Check if we already added this light from a different subsector { - gl_AddLightToList(group, light, modellightdata); + modellightdata.AddLightToList(group, light); addedLights.push_back(light); } } diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index e1f551b62ad..e7f719c628c 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -276,6 +276,17 @@ class GLWall mDrawer = drawer; } + GLWall(const GLWall &other) + { + memcpy(this, &other, sizeof(GLWall)); + } + + GLWall & operator=(const GLWall &other) + { + memcpy(this, &other, sizeof(GLWall)); + return *this; + } + void Process(seg_t *seg, sector_t *frontsector, sector_t *backsector); void ProcessLowerMiniseg(seg_t *seg, sector_t *frontsector, sector_t *backsector); void Draw(int pass); @@ -349,6 +360,18 @@ class GLFlat void SetFrom3DFloor(F3DFloor *rover, bool top, bool underside); void ProcessSector(sector_t * frontsector); void Draw(int pass, bool trans); + + GLFlat(const GLFlat &other) + { + memcpy(this, &other, sizeof(GLFlat)); + } + + GLFlat & operator=(const GLFlat &other) + { + memcpy(this, &other, sizeof(GLFlat)); + return *this; + } + }; @@ -418,6 +441,18 @@ class GLSprite // Lines start-end and fdiv must intersect. double CalcIntersectionVertex(GLWall * w2); + + GLSprite(const GLSprite &other) + { + memcpy(this, &other, sizeof(GLSprite)); + } + + GLSprite & operator=(const GLSprite &other) + { + memcpy(this, &other, sizeof(GLSprite)); + return *this; + } + }; inline float Dist2(float x1,float y1,float x2,float y2) diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 919ce374c0c..43687f523f0 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -34,10 +34,10 @@ #include "doomdata.h" #include "portal.h" #include "g_levellocals.h" +#include "hwrenderer/dynlights/hw_dynlightdata.h" #include "gl/system/gl_cvars.h" #include "gl/renderer/gl_lightdata.h" -#include "gl/dynlights/gl_dynlight.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" #include "gl/scene/gl_scenedrawer.h" @@ -55,7 +55,8 @@ void FDrawInfo::AddWall(GLWall *wall) { wall->ViewDistance = (r_viewpoint.Pos - (wall->seg->linedef->v1->fPos() + wall->seg->linedef->Delta() / 2)).XY().LengthSquared(); if (gl.buffermethod == BM_DEFERRED) wall->MakeVertices(true); - drawlists[GLDL_TRANSLUCENT].AddWall(wall); + auto newwall = drawlists[GLDL_TRANSLUCENT].NewWall(); + *newwall = *wall; } else { @@ -77,8 +78,8 @@ void FDrawInfo::AddWall(GLWall *wall) list = masked ? GLDL_MASKEDWALLS : GLDL_PLAINWALLS; } if (gl.buffermethod == BM_DEFERRED) wall->MakeVertices(false); - drawlists[list].AddWall(wall); - + auto newwall = drawlists[list].NewWall(); + *newwall = *wall; } } @@ -172,7 +173,8 @@ void GLWall::PutPortal(int ptype) { // draw a reflective layer over the mirror type=RENDERWALL_MIRRORSURFACE; - gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].AddWall(this); + auto newwall = gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].NewWall(); + *newwall = *this; } break; @@ -1085,6 +1087,7 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary, // restore some values that have been altered in this function glseg=glsave; flags&=~(GLT_CLAMPX|GLT_CLAMPY|GLWF_NOSPLITUPPER|GLWF_NOSPLITLOWER); + RenderStyle = STYLE_Normal; } diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 0fb2e38bf77..05e12ed086d 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -27,6 +27,7 @@ #include "g_levellocals.h" #include "actor.h" #include "actorinlines.h" +#include "hwrenderer/dynlights/hw_dynlightdata.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_cvars.h" @@ -34,7 +35,6 @@ #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_renderer.h" #include "gl/data/gl_vertexbuffer.h" -#include "gl/dynlights/gl_dynlight.h" #include "gl/dynlights/gl_lightbuffer.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" @@ -73,7 +73,7 @@ void GLWall::SetupLights() lightdata.Clear(); auto normal = glseg.Normal(); - p.Set(normal, -normal.X * glseg.x1 - normal.Y * glseg.y1); + p.Set(normal, -normal.X * glseg.x1 - normal.Z * glseg.y1); FLightNode *node; if (seg->sidedef == NULL) @@ -139,7 +139,7 @@ void GLWall::SetupLights() } if (outcnt[0]!=4 && outcnt[1]!=4 && outcnt[2]!=4 && outcnt[3]!=4) { - gl_GetLight(seg->frontsector->PortalGroup, p, node->lightsource, true, lightdata); + lightdata.GetLight(seg->frontsector->PortalGroup, p, node->lightsource, true); } } } diff --git a/src/gl/system/gl_cvars.h b/src/gl/system/gl_cvars.h index 51ab642de76..ec4784440d1 100644 --- a/src/gl/system/gl_cvars.h +++ b/src/gl/system/gl_cvars.h @@ -23,7 +23,7 @@ EXTERN_CVAR(Int, gl_weaponlight) EXTERN_CVAR (Bool, gl_lights); EXTERN_CVAR (Bool, gl_attachedlights); -EXTERN_CVAR (Bool, gl_lights_checkside); + EXTERN_CVAR (Bool, gl_light_sprites); EXTERN_CVAR (Bool, gl_light_particles); EXTERN_CVAR (Bool, gl_light_shadowmap); diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/hwrenderer/dynlights/hw_dynlightdata.cpp similarity index 79% rename from src/gl/dynlights/gl_dynlight1.cpp rename to src/hwrenderer/dynlights/hw_dynlightdata.cpp index 9c3e40ad019..c47a331243d 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/hwrenderer/dynlights/hw_dynlightdata.cpp @@ -1,7 +1,7 @@ // //--------------------------------------------------------------------------- // -// Copyright(C) 2002-2016 Christoph Oelckers +// Copyright(C) 2002-2018 Christoph Oelckers // All rights reserved. // // This program is free software: you can redistribute it and/or modify @@ -33,14 +33,7 @@ #include "actorinlines.h" #include "a_dynlight.h" -#include "gl/system/gl_interface.h" -#include "gl/renderer/gl_renderer.h" -#include "gl/renderer/gl_lightdata.h" -#include "gl/dynlights/gl_dynlight.h" -#include "gl/scene/gl_drawinfo.h" -#include "gl/scene/gl_portal.h" -#include "gl/shaders/gl_shader.h" -#include "gl/textures/gl_material.h" +#include "hw_dynlightdata.h" //========================================================================== @@ -49,10 +42,9 @@ // //========================================================================== -CVAR (Bool, gl_lights_checkside, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); +// These shouldn't be called 'gl...' anymore... CVAR (Bool, gl_light_sprites, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR (Bool, gl_light_particles, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); -CVAR (Bool, gl_light_shadowmap, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR(Int, gl_attenuate, -1, 0); // This is mainly a debug option. @@ -61,7 +53,7 @@ CVAR(Int, gl_attenuate, -1, 0); // This is mainly a debug option. // Sets up the parameters to render one dynamic light onto one plane // //========================================================================== -bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FDynLightData &ldata) +bool FDynLightData::GetLight(int group, Plane & p, ADynamicLight * light, bool checkside) { DVector3 pos = light->PosRelative(group); float radius = (light->GetRadius()); @@ -70,12 +62,12 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FD if (radius <= 0.f) return false; if (dist > radius) return false; - if (checkside && gl_lights_checkside && p.PointOnSide(pos.X, pos.Z, pos.Y)) + if (checkside && p.PointOnSide(pos.X, pos.Z, pos.Y)) { return false; } - gl_AddLightToList(group, light, ldata); + AddLightToList(group, light); return true; } @@ -84,7 +76,7 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FD // Add one dynamic light to the light data list // //========================================================================== -void gl_AddLightToList(int group, ADynamicLight * light, FDynLightData &ldata) +void FDynLightData::AddLightToList(int group, ADynamicLight * light) { int i = 0; @@ -117,10 +109,10 @@ void gl_AddLightToList(int group, ADynamicLight * light, FDynLightData &ldata) i = 1; } - // Store attenuate flag in the sign bit of the float. - float shadowIndex = GLRenderer->mShadowMap.ShadowMapIndex(light) + 1.0f; + float shadowIndex = light->mShadowmapIndex + 1.0f; bool attenuate; + // Store attenuate flag in the sign bit of the float. if (gl_attenuate == -1) attenuate = !!(light->lightflags & LF_ATTENUATE); else attenuate = !!gl_attenuate; @@ -145,7 +137,7 @@ void gl_AddLightToList(int group, ADynamicLight * light, FDynLightData &ldata) spotDirZ = -light->Angles.Yaw.Sin() * xzLen; } - float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(16)]; + float *data = &arrays[i][arrays[i].Reserve(16)]; data[0] = pos.X; data[1] = pos.Z; data[2] = pos.Y; diff --git a/src/gl/dynlights/gl_dynlight.h b/src/hwrenderer/dynlights/hw_dynlightdata.h similarity index 88% rename from src/gl/dynlights/gl_dynlight.h rename to src/hwrenderer/dynlights/hw_dynlightdata.h index 99979f034a4..cfa47bc69d4 100644 --- a/src/gl/dynlights/gl_dynlight.h +++ b/src/hwrenderer/dynlights/hw_dynlightdata.h @@ -53,13 +53,11 @@ struct FDynLightData if (siz[1] > max) siz[1] = max; if (siz[2] > max) siz[2] = max; } -}; - + + bool GetLight(int group, Plane & p, ADynamicLight * light, bool checkside); + void AddLightToList(int group, ADynamicLight * light); - -bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FDynLightData &data); -void gl_AddLightToList(int group, ADynamicLight * light, FDynLightData &ldata); -void gl_UploadLights(FDynLightData &data); +}; #endif diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index cf79afc6f1a..6f38e0ae894 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -994,7 +994,7 @@ void G_SerializeLevel(FSerializer &arc, bool hubload) arc("zones", level.Zones); arc("lineportals", level.linePortals); arc("sectorportals", level.sectorPortals); - if (arc.isReading()) P_CollectLinkedPortals(); + if (arc.isReading()) P_FinalizePortals(); // [ZZ] serialize events E_SerializeEvents(arc); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 6241bf00a9b..8e8bc1ed2b6 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -4145,7 +4145,8 @@ void P_SetupLevel (const char *lumpname, int position) times[16].Clock(); if (reloop) P_LoopSidedefs (false); PO_Init (); // Initialize the polyobjs - P_FinalizePortals(); // finalize line portals after polyobjects have been initialized. This info is needed for properly flagging them. + if (!savegamerestore) + P_FinalizePortals(); // finalize line portals after polyobjects have been initialized. This info is needed for properly flagging them. times[16].Unclock(); assert(sidetemp != NULL); @@ -4381,4 +4382,4 @@ CCMD(dumpgeometry) } } } -} \ No newline at end of file +} diff --git a/src/polyrenderer/drawers/poly_drawer32.h b/src/polyrenderer/drawers/poly_drawer32.h index 579330ad193..0ec21ff9173 100644 --- a/src/polyrenderer/drawers/poly_drawer32.h +++ b/src/polyrenderer/drawers/poly_drawer32.h @@ -242,6 +242,7 @@ namespace TriScreenDrawerModes { if (BlendT::Mode == (int)BlendModes::Opaque) { + fgcolor.a = 255; return fgcolor; } else if (BlendT::Mode == (int)BlendModes::Masked) diff --git a/src/polyrenderer/drawers/poly_drawer32_sse2.h b/src/polyrenderer/drawers/poly_drawer32_sse2.h index 33af938dc55..11d08c59c94 100644 --- a/src/polyrenderer/drawers/poly_drawer32_sse2.h +++ b/src/polyrenderer/drawers/poly_drawer32_sse2.h @@ -250,6 +250,7 @@ namespace TriScreenDrawerModes { __m128i outcolor = fgcolor; outcolor = _mm_packus_epi16(outcolor, _mm_setzero_si128()); + outcolor = _mm_or_si128(outcolor, _mm_set1_epi32(0xff000000)); return outcolor; } else if (BlendT::Mode == (int)BlendModes::Masked) diff --git a/src/polyrenderer/poly_renderer.cpp b/src/polyrenderer/poly_renderer.cpp index 6bac004e025..f5d8f612fac 100644 --- a/src/polyrenderer/poly_renderer.cpp +++ b/src/polyrenderer/poly_renderer.cpp @@ -62,11 +62,6 @@ void PolyRenderer::RenderView(player_t *player, DCanvas *target) RenderTarget = target; RenderToCanvas = false; - int width = SCREENWIDTH; - int height = SCREENHEIGHT; - float trueratio; - ActiveRatio(width, height, &trueratio); - //viewport->SetViewport(&Thread, width, height, trueratio); RenderActorView(player->mo, false); @@ -78,24 +73,40 @@ void PolyRenderer::RenderView(player_t *player, DCanvas *target) void PolyRenderer::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines) { - const bool savedviewactive = viewactive; - - viewwidth = width; + // Save a bunch of silly globals: + auto savedViewpoint = Viewpoint; + auto savedViewwindow = Viewwindow; + auto savedviewwindowx = viewwindowx; + auto savedviewwindowy = viewwindowy; + auto savedviewwidth = viewwidth; + auto savedviewheight = viewheight; + auto savedviewactive = viewactive; + auto savedRenderTarget = RenderTarget; + + // Setup the view: RenderTarget = canvas; RenderToCanvas = true; R_SetWindow(Viewpoint, Viewwindow, 12, width, height, height, true); - //viewport->SetViewport(&Thread, width, height, Viewwindow.WidescreenRatio); viewwindowx = x; viewwindowy = y; viewactive = true; + // Render: RenderActorView(actor, dontmaplines); Threads.MainThread()->FlushDrawQueue(); DrawerThreads::WaitForWorkers(); - RenderTarget = nullptr; RenderToCanvas = false; + + // Restore silly globals: + Viewpoint = savedViewpoint; + Viewwindow = savedViewwindow; + viewwindowx = savedviewwindowx; + viewwindowy = savedviewwindowy; + viewwidth = savedviewwidth; + viewheight = savedviewheight; viewactive = savedviewactive; + RenderTarget = savedRenderTarget; } void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines) @@ -114,6 +125,13 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines) P_FindParticleSubsectors(); PO_LinkToSubsectors(); + static bool firstcall = true; + if (firstcall) + { + swrenderer::R_InitFuzzTable(RenderTarget->GetPitch()); + firstcall = false; + } + swrenderer::R_UpdateFuzzPosFrameStart(); if (APART(R_OldBlend)) NormalLight.Maps = realcolormaps.Maps; @@ -124,10 +142,15 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines) PolyCameraLight::Instance()->SetCamera(Viewpoint, RenderTarget, actor); //Viewport->SetupFreelook(); - ActorRenderFlags savedflags = Viewpoint.camera->renderflags; - // Never draw the player unless in chasecam mode - if (!Viewpoint.showviewer) - Viewpoint.camera->renderflags |= RF_INVISIBLE; + ActorRenderFlags savedflags = 0; + if (Viewpoint.camera) + { + savedflags = Viewpoint.camera->renderflags; + + // Never draw the player unless in chasecam mode + if (!Viewpoint.showviewer) + Viewpoint.camera->renderflags |= RF_INVISIBLE; + } ScreenTriangle::FuzzStart = (ScreenTriangle::FuzzStart + 14) % FUZZTABLE; @@ -145,7 +168,8 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines) Scene.RenderTranslucent(&mainViewpoint); PlayerSprites.Render(Threads.MainThread()); - Viewpoint.camera->renderflags = savedflags; + if (Viewpoint.camera) + Viewpoint.camera->renderflags = savedflags; interpolator.RestoreInterpolations (); } diff --git a/src/polyrenderer/scene/poly_scene.cpp b/src/polyrenderer/scene/poly_scene.cpp index 378264ef7b2..b84608a4ad9 100644 --- a/src/polyrenderer/scene/poly_scene.cpp +++ b/src/polyrenderer/scene/poly_scene.cpp @@ -49,6 +49,7 @@ RenderPolyScene::~RenderPolyScene() void RenderPolyScene::Render(PolyPortalViewpoint *viewpoint) { + PolyPortalViewpoint *oldviewpoint = CurrentViewpoint; CurrentViewpoint = viewpoint; PolyRenderThread *thread = PolyRenderer::Instance()->Threads.MainThread(); @@ -85,7 +86,7 @@ void RenderPolyScene::Render(PolyPortalViewpoint *viewpoint) RenderPortals(); - CurrentViewpoint = nullptr; + CurrentViewpoint = oldviewpoint; } void RenderPolyScene::RenderSectors() @@ -321,11 +322,11 @@ void RenderPolyScene::RenderPortals() bool foggy = false; if (CurrentViewpoint->PortalDepth < r_portal_recursions) { - for (auto &portal : thread->SectorPortals) - portal->Render(CurrentViewpoint->PortalDepth + 1); + for (size_t i = CurrentViewpoint->SectorPortalsStart; i < CurrentViewpoint->SectorPortalsEnd; i++) + thread->SectorPortals[i]->Render(CurrentViewpoint->PortalDepth + 1); - for (auto &portal : thread->LinePortals) - portal->Render(CurrentViewpoint->PortalDepth + 1); + for (size_t i = CurrentViewpoint->LinePortalsStart; i < CurrentViewpoint->LinePortalsEnd; i++) + thread->LinePortals[i]->Render(CurrentViewpoint->PortalDepth + 1); } else // Fill with black { @@ -335,8 +336,9 @@ void RenderPolyScene::RenderPortals() args.SetClipPlane(0, CurrentViewpoint->PortalPlane); args.SetStyle(TriBlendMode::FillOpaque); - for (auto &portal : thread->SectorPortals) + for (size_t i = CurrentViewpoint->SectorPortalsStart; i < CurrentViewpoint->SectorPortalsEnd; i++) { + const auto &portal = thread->SectorPortals[i]; args.SetStencilTestValue(portal->StencilValue); args.SetWriteStencil(true, portal->StencilValue + 1); for (const auto &verts : portal->Shape) @@ -345,8 +347,9 @@ void RenderPolyScene::RenderPortals() } } - for (auto &portal : thread->LinePortals) + for (size_t i = CurrentViewpoint->LinePortalsStart; i < CurrentViewpoint->LinePortalsEnd; i++) { + const auto &portal = thread->LinePortals[i]; args.SetStencilTestValue(portal->StencilValue); args.SetWriteStencil(true, portal->StencilValue + 1); for (const auto &verts : portal->Shape) @@ -359,19 +362,22 @@ void RenderPolyScene::RenderPortals() void RenderPolyScene::RenderTranslucent(PolyPortalViewpoint *viewpoint) { + PolyPortalViewpoint *oldviewpoint = CurrentViewpoint; CurrentViewpoint = viewpoint; PolyRenderThread *thread = PolyRenderer::Instance()->Threads.MainThread(); - PolyTriangleDrawer::SetTransform(thread->DrawQueue, thread->FrameMemory->NewObject(CurrentViewpoint->WorldToClip)); + Mat4f *transform = thread->FrameMemory->NewObject(CurrentViewpoint->WorldToClip); if (CurrentViewpoint->PortalDepth < r_portal_recursions) { - for (auto it = thread->SectorPortals.rbegin(); it != thread->SectorPortals.rend(); ++it) + for (size_t i = CurrentViewpoint->SectorPortalsEnd; i > CurrentViewpoint->SectorPortalsStart; i--) { - auto &portal = *it; + auto &portal = thread->SectorPortals[i - 1]; portal->RenderTranslucent(); - + + PolyTriangleDrawer::SetTransform(thread->DrawQueue, transform); + PolyDrawArgs args; args.SetStencilTestValue(portal->StencilValue + 1); args.SetWriteStencil(true, CurrentViewpoint->StencilValue + 1); @@ -383,11 +389,13 @@ void RenderPolyScene::RenderTranslucent(PolyPortalViewpoint *viewpoint) } } - for (auto it = thread->LinePortals.rbegin(); it != thread->LinePortals.rend(); ++it) + for (size_t i = CurrentViewpoint->LinePortalsEnd; i > CurrentViewpoint->LinePortalsStart; i--) { - auto &portal = *it; + auto &portal = thread->LinePortals[i - 1]; portal->RenderTranslucent(); + PolyTriangleDrawer::SetTransform(thread->DrawQueue, transform); + PolyDrawArgs args; args.SetStencilTestValue(portal->StencilValue + 1); args.SetWriteStencil(true, CurrentViewpoint->StencilValue + 1); @@ -400,35 +408,27 @@ void RenderPolyScene::RenderTranslucent(PolyPortalViewpoint *viewpoint) } } + PolyTriangleDrawer::SetTransform(thread->DrawQueue, transform); + PolyMaskedCycles.Clock(); // Draw all translucent objects back to front - if (CurrentViewpoint->ObjectsEnd > CurrentViewpoint->ObjectsStart) + std::stable_sort( + thread->TranslucentObjects.begin() + CurrentViewpoint->ObjectsStart, + thread->TranslucentObjects.begin() + CurrentViewpoint->ObjectsEnd, + [](auto a, auto b) { return *a < *b; }); + + auto objects = thread->TranslucentObjects.data(); + for (size_t i = CurrentViewpoint->ObjectsEnd; i > CurrentViewpoint->ObjectsStart; i--) { - std::stable_sort( - thread->TranslucentObjects.begin() + CurrentViewpoint->ObjectsStart, - thread->TranslucentObjects.begin() + CurrentViewpoint->ObjectsEnd, - [](auto a, auto b) { return *a < *b; }); - - size_t i = CurrentViewpoint->ObjectsEnd - 1; - size_t start = CurrentViewpoint->ObjectsStart; - auto objects = thread->TranslucentObjects.data(); - while (true) - { - PolyTranslucentObject *obj = objects[i]; - obj->Render(thread, CurrentViewpoint->PortalPlane); - obj->~PolyTranslucentObject(); - if (i == start) - break; - i--; - } + PolyTranslucentObject *obj = objects[i - 1]; + obj->Render(thread, CurrentViewpoint->PortalPlane); + obj->~PolyTranslucentObject(); } - thread->TranslucentObjects.clear(); - PolyMaskedCycles.Unclock(); - CurrentViewpoint = nullptr; + CurrentViewpoint = oldviewpoint; } ///////////////////////////////////////////////////////////////////////////// diff --git a/src/sc_man_scanner.re b/src/sc_man_scanner.re index 0dd74009aab..3ef66b7609e 100644 --- a/src/sc_man_scanner.re +++ b/src/sc_man_scanner.re @@ -209,6 +209,7 @@ std2: 'version' { RET(ParseVersion >= MakeVersion(2, 4, 0)? TK_Version : TK_Identifier); } 'action' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Action : TK_Identifier); } 'readonly' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_ReadOnly : TK_Identifier); } + 'internal' { RET(ParseVersion >= MakeVersion(3, 4, 0)? TK_Internal : TK_Identifier); } 'let' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Let : TK_Identifier); } /* Actor state options */ diff --git a/src/sc_man_tokens.h b/src/sc_man_tokens.h index 33be1c6ae61..dfe49518ae8 100644 --- a/src/sc_man_tokens.h +++ b/src/sc_man_tokens.h @@ -138,6 +138,7 @@ xx(TK_Meta, "'meta'") xx(TK_Deprecated, "'deprecated'") xx(TK_Version, "'version'") xx(TK_ReadOnly, "'readonly'") +xx(TK_Internal, "'internal'") xx(TK_CanRaise, "'canraise'") xx(TK_Fast, "'fast'") diff --git a/src/scripting/zscript/zcc-parse.lemon b/src/scripting/zscript/zcc-parse.lemon index 34ebd9149e0..11847217fd8 100644 --- a/src/scripting/zscript/zcc-parse.lemon +++ b/src/scripting/zscript/zcc-parse.lemon @@ -1120,6 +1120,7 @@ decl_flag(X) ::= FINAL(T). { X.Int = ZCC_Final; X.SourceLoc = T.SourceLoc; } decl_flag(X) ::= META(T). { X.Int = ZCC_Meta; X.SourceLoc = T.SourceLoc; } decl_flag(X) ::= TRANSIENT(T). { X.Int = ZCC_Transient; X.SourceLoc = T.SourceLoc; } decl_flag(X) ::= READONLY(T). { X.Int = ZCC_ReadOnly; X.SourceLoc = T.SourceLoc; } +decl_flag(X) ::= INTERNAL(T). { X.Int = ZCC_Internal; X.SourceLoc = T.SourceLoc; } decl_flag(X) ::= VIRTUAL(T). { X.Int = ZCC_Virtual; X.SourceLoc = T.SourceLoc; } decl_flag(X) ::= OVERRIDE(T). { X.Int = ZCC_Override; X.SourceLoc = T.SourceLoc; } decl_flag(X) ::= VARARG(T). { X.Int = ZCC_VarArg; X.SourceLoc = T.SourceLoc; } diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index 1068501d681..d782383e7f9 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -1241,6 +1241,7 @@ bool ZCCCompiler::CompileFields(PContainerType *type, TArrayFlags & ZCC_Protected) varflags |= VARF_Protected; if (field->Flags & ZCC_Deprecated) varflags |= VARF_Deprecated; if (field->Flags & ZCC_ReadOnly) varflags |= VARF_ReadOnly; + if (field->Flags & ZCC_Internal) varflags |= VARF_InternalAccess; if (field->Flags & ZCC_Transient) varflags |= VARF_Transient; if (mVersion >= MakeVersion(2, 4, 0)) { @@ -2327,7 +2328,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool } while (t != f->Type); } - int notallowed = ZCC_Latent | ZCC_Meta | ZCC_ReadOnly | ZCC_Abstract; + int notallowed = ZCC_Latent | ZCC_Meta | ZCC_ReadOnly | ZCC_Abstract | ZCC_Internal; if (f->Flags & notallowed) { diff --git a/src/scripting/zscript/zcc_parser.cpp b/src/scripting/zscript/zcc_parser.cpp index 6902753da9a..f067311efdf 100644 --- a/src/scripting/zscript/zcc_parser.cpp +++ b/src/scripting/zscript/zcc_parser.cpp @@ -149,6 +149,7 @@ static void InitTokenMap() TOKENDEF (TK_Deprecated, ZCC_DEPRECATED); TOKENDEF (TK_Version, ZCC_VERSION); TOKENDEF (TK_ReadOnly, ZCC_READONLY); + TOKENDEF (TK_Internal, ZCC_INTERNAL); TOKENDEF ('{', ZCC_LBRACE); TOKENDEF ('}', ZCC_RBRACE); TOKENDEF (TK_Struct, ZCC_STRUCT); diff --git a/src/scripting/zscript/zcc_parser.h b/src/scripting/zscript/zcc_parser.h index 5f0889fd2e4..1089b2ed8bd 100644 --- a/src/scripting/zscript/zcc_parser.h +++ b/src/scripting/zscript/zcc_parser.h @@ -63,6 +63,7 @@ enum ZCC_ClearScope = 1 << 19, ZCC_VirtualScope = 1 << 20, ZCC_Version = 1 << 21, + ZCC_Internal = 1 << 22, }; // Function parameter modifiers diff --git a/src/swrenderer/drawers/r_draw_span32.h b/src/swrenderer/drawers/r_draw_span32.h index 15f24ffcfe2..2907037936f 100644 --- a/src/swrenderer/drawers/r_draw_span32.h +++ b/src/swrenderer/drawers/r_draw_span32.h @@ -371,6 +371,7 @@ namespace swrenderer if (BlendT::Mode == (int)SpanBlendModes::Opaque) { + fgcolor.a = 255; return fgcolor; } else if (BlendT::Mode == (int)SpanBlendModes::Masked) diff --git a/src/swrenderer/drawers/r_draw_span32_sse2.h b/src/swrenderer/drawers/r_draw_span32_sse2.h index 92a50f0ff58..7b0af6257e7 100644 --- a/src/swrenderer/drawers/r_draw_span32_sse2.h +++ b/src/swrenderer/drawers/r_draw_span32_sse2.h @@ -414,6 +414,7 @@ namespace swrenderer { __m128i outcolor = fgcolor; outcolor = _mm_packus_epi16(outcolor, _mm_setzero_si128()); + outcolor = _mm_or_si128(outcolor, _mm_set1_epi32(0xff000000)); return outcolor; } else if (BlendT::Mode == (int)SpanBlendModes::Masked) diff --git a/src/swrenderer/drawers/r_draw_sprite32.h b/src/swrenderer/drawers/r_draw_sprite32.h index 3437db81e28..7032b05d5b1 100644 --- a/src/swrenderer/drawers/r_draw_sprite32.h +++ b/src/swrenderer/drawers/r_draw_sprite32.h @@ -322,6 +322,7 @@ namespace swrenderer if (BlendT::Mode == (int)SpriteBlendModes::Opaque) { + fgcolor.a = 255; return fgcolor; } else if (BlendT::Mode == (int)SpriteBlendModes::Shaded) diff --git a/src/swrenderer/drawers/r_draw_sprite32_sse2.h b/src/swrenderer/drawers/r_draw_sprite32_sse2.h index 6463402d823..49b62d64d69 100644 --- a/src/swrenderer/drawers/r_draw_sprite32_sse2.h +++ b/src/swrenderer/drawers/r_draw_sprite32_sse2.h @@ -368,6 +368,7 @@ namespace swrenderer { __m128i outcolor = fgcolor; outcolor = _mm_packus_epi16(outcolor, _mm_setzero_si128()); + outcolor = _mm_or_si128(outcolor, _mm_set1_epi32(0xff000000)); return outcolor; } else if (BlendT::Mode == (int)SpriteBlendModes::Shaded) diff --git a/src/swrenderer/drawers/r_draw_wall32.h b/src/swrenderer/drawers/r_draw_wall32.h index 972d5c1dabd..64c6a8d446a 100644 --- a/src/swrenderer/drawers/r_draw_wall32.h +++ b/src/swrenderer/drawers/r_draw_wall32.h @@ -285,6 +285,7 @@ namespace swrenderer if (BlendT::Mode == (int)WallBlendModes::Opaque) { + fgcolor.a = 255; return fgcolor; } else if (BlendT::Mode == (int)WallBlendModes::Masked) diff --git a/src/swrenderer/drawers/r_draw_wall32_sse2.h b/src/swrenderer/drawers/r_draw_wall32_sse2.h index e51c11165b3..e0b0c0d77f5 100644 --- a/src/swrenderer/drawers/r_draw_wall32_sse2.h +++ b/src/swrenderer/drawers/r_draw_wall32_sse2.h @@ -330,6 +330,7 @@ namespace swrenderer { __m128i outcolor = fgcolor; outcolor = _mm_packus_epi16(outcolor, _mm_setzero_si128()); + outcolor = _mm_or_si128(outcolor, _mm_set1_epi32(0xff000000)); return outcolor; } else if (BlendT::Mode == (int)WallBlendModes::Masked) diff --git a/src/swrenderer/scene/r_scene.cpp b/src/swrenderer/scene/r_scene.cpp index d366324524e..3f7db6950b3 100644 --- a/src/swrenderer/scene/r_scene.cpp +++ b/src/swrenderer/scene/r_scene.cpp @@ -332,13 +332,19 @@ namespace swrenderer { auto viewport = MainThread()->Viewport.get(); - const bool savedviewactive = viewactive; - auto savedtarget = viewport->RenderTarget; - - viewwidth = width; + // Save a bunch of silly globals: + auto savedViewpoint = viewport->viewpoint; + auto savedViewwindow = viewport->viewwindow; + auto savedviewwindowx = viewwindowx; + auto savedviewwindowy = viewwindowy; + auto savedviewwidth = viewwidth; + auto savedviewheight = viewheight; + auto savedviewactive = viewactive; + auto savedRenderTarget = viewport->RenderTarget; + + // Setup the view: viewport->RenderTarget = canvas; viewport->RenderingToCanvas = true; - R_SetWindow(MainThread()->Viewport->viewpoint, MainThread()->Viewport->viewwindow, 12, width, height, height, true); viewwindowx = x; viewwindowy = y; @@ -347,14 +353,23 @@ namespace swrenderer if (r_models) PolyTriangleDrawer::ClearBuffers(viewport->RenderTarget); + // Render: RenderActorView(actor, dontmaplines); DrawerWaitCycles.Clock(); DrawerThreads::WaitForWorkers(); DrawerWaitCycles.Unclock(); - viewport->RenderTarget = savedtarget; viewport->RenderingToCanvas = false; + + // Restore silly globals: + viewport->viewpoint = savedViewpoint; + viewport->viewwindow = savedViewwindow; + viewwindowx = savedviewwindowx; + viewwindowy = savedviewwindowy; + viewwidth = savedviewwidth; + viewheight = savedviewheight; viewactive = savedviewactive; + viewport->RenderTarget = savedRenderTarget; } void RenderScene::Deinit() diff --git a/src/tarray.h b/src/tarray.h index 5a11e4a5b90..153fcd0ba5b 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -560,6 +560,10 @@ class TStaticPointedArray { return Array[index]; } + T &At(size_t index) const + { + return Array[index]; + } unsigned int Size() const { return Count; diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index ac72a8027df..bf04fa86a6d 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -1079,7 +1079,8 @@ void FTexture::CreateDefaultBrightmap() // Check for brightmaps if (UseBasePalette() && TexMan.HasGlobalBrightmap && UseType != ETextureType::Decal && UseType != ETextureType::MiscPatch && UseType != ETextureType::FontChar && - Brightmap == NULL && bWarped == 0 + Brightmap == NULL && bWarped == 0 && + GetPixels(DefaultRenderStyle()) ) { // May have one - let's check when we use this texture diff --git a/src/v_2ddrawer.cpp b/src/v_2ddrawer.cpp index e860d803426..ada1b5878bb 100644 --- a/src/v_2ddrawer.cpp +++ b/src/v_2ddrawer.cpp @@ -30,6 +30,7 @@ #include "templates.h" #include "r_utility.h" #include "v_video.h" +#include "g_levellocals.h" EXTERN_CVAR(Float, transsouls) @@ -324,6 +325,11 @@ void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints, // is necessary in order to best reproduce Doom's original lighting. double map = (NUMCOLORMAPS * 2.) - ((lightlevel + 12) * (NUMCOLORMAPS / 128.)); double fadelevel = clamp((map - 12) / NUMCOLORMAPS, 0.0, 1.0); + // handle the brighter light modes of the hardware renderer. + if (vid_rendermode == 4 && (level.lightmode < 2 || level.lightmode == 4)) + { + fadelevel = pow(fadelevel, 1.3); + } RenderCommand poly; diff --git a/src/version.h b/src/version.h index afda99a21f8..30513f9675e 100644 --- a/src/version.h +++ b/src/version.h @@ -57,7 +57,7 @@ const char *GetVersionString(); #define RC_PRODUCTVERSION2 VERSIONSTR // These are for content versioning. The current state is '3.3'. #define VER_MAJOR 3 -#define VER_MINOR 3 +#define VER_MINOR 4 #define VER_REVISION 0 // Version identifier for network games. diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 85c77e35d5b..d769af6e107 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -2193,7 +2193,6 @@ OptionMenu "GLLightOptions" protected Option "$TCMNU_DYNLIGHTS", "r_dynlights", "OnOff" Option "$GLLIGHTMNU_LIGHTSENABLED", gl_lights, "OnOff" Option "$GLLIGHTMNU_LIGHTDEFS", gl_attachedlights, "YesNo" - Option "$GLLIGHTMNU_CLIPLIGHTS", gl_lights_checkside, "YesNo" Option "$GLLIGHTMNU_LIGHTSPRITES", gl_light_sprites, "YesNo" Option "$GLLIGHTMNU_LIGHTPARTICLES", gl_light_particles, "YesNo" Option "$GLLIGHTMNU_LIGHTSHADOWMAP", gl_light_shadowmap, "YesNo" diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 31531ed281e..1daf046283a 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -1,4 +1,4 @@ -version "3.3" +version "3.4" #include "zscript/base.txt" #include "zscript/sounddata.txt" #include "zscript/mapdata.txt" diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 6faba670590..30df80759ca 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -580,7 +580,7 @@ struct LevelLocals native native Array<@Line> Lines; native Array<@Side> Sides; native readonly Array<@Vertex> Vertexes; - native Array<@SectorPortal> SectorPortals; + native internal Array<@SectorPortal> SectorPortals; native readonly int time; native readonly int maptime; diff --git a/wadsrc/static/zscript/level_compatibility.txt b/wadsrc/static/zscript/level_compatibility.txt index c2d1834e2ea..4fc1ba0ba8b 100644 --- a/wadsrc/static/zscript/level_compatibility.txt +++ b/wadsrc/static/zscript/level_compatibility.txt @@ -666,6 +666,22 @@ class LevelCompatibility play break; } + case '9C14350A111C3DC6A8AF04D950E6DDDB': // ma_val.pk3 map01 + { + // Missing wall textures with hardware renderer + OffsetSectorPlane(7072, Sector.floor, -48); + OffsetSectorPlane(7073, Sector.floor, -32); + // Missing teleporting monsters + SetThingFlags(376, 0x200); + SetThingFlags(377, 0x300); + for (int i = 437; i < 449; ++i) + { + SetThingFlags(i, 0x600); + } + // Stuck imp + SetThingXY(8, 1200, -1072); + break; + } } } @@ -673,6 +689,7 @@ class LevelCompatibility play private static native void AddSectorTag(int sector, int tag); private static native void OffsetSectorPlane(int sector, int plane, double offset); private static native void SetThingSkills(int thing, int skills); + private static native void SetThingXY(int thing, double x, double y); private static native void SetThingZ(int thing, double z); private static native void SetThingFlags(int thing, int flags); private static native void SetVertex(uint vertex, double x, double y); diff --git a/wadsrc/static/zscript/mapdata.txt b/wadsrc/static/zscript/mapdata.txt index fb62faff725..f20a9b2ebfb 100644 --- a/wadsrc/static/zscript/mapdata.txt +++ b/wadsrc/static/zscript/mapdata.txt @@ -334,7 +334,7 @@ struct Sector native play native SectorAction SecActTarget; - native uint Portals[2]; + native internal uint Portals[2]; native readonly int PortalGroup; native readonly int sectornum;