mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 07:11:54 +00:00
- made wall draw code API independent.
This commit is contained in:
parent
7897f26abf
commit
8ffeb7812f
12 changed files with 275 additions and 264 deletions
|
@ -209,8 +209,6 @@ void FDrawInfo::StartScene()
|
||||||
outer = gl_drawinfo;
|
outer = gl_drawinfo;
|
||||||
gl_drawinfo = this;
|
gl_drawinfo = this;
|
||||||
for (int i = 0; i < GLDL_TYPES; i++) drawlists[i].Reset();
|
for (int i = 0; i < GLDL_TYPES; i++) drawlists[i].Reset();
|
||||||
decals[0].Clear();
|
|
||||||
decals[1].Clear();
|
|
||||||
hudsprites.Clear();
|
hudsprites.Clear();
|
||||||
vpIndex = 0;
|
vpIndex = 0;
|
||||||
|
|
||||||
|
@ -256,13 +254,6 @@ std::pair<FFlatVertex *, unsigned int> FDrawInfo::AllocVertices(unsigned int cou
|
||||||
return std::make_pair(p, index);
|
return std::make_pair(p, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLDecal *FDrawInfo::AddDecal(bool onmirror)
|
|
||||||
{
|
|
||||||
auto decal = (GLDecal*)RenderDataAllocator.Alloc(sizeof(GLDecal));
|
|
||||||
decals[onmirror ? 1 : 0].Push(decal);
|
|
||||||
return decal;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FDrawInfo::UploadLights(FDynLightData &data)
|
int FDrawInfo::UploadLights(FDynLightData &data)
|
||||||
{
|
{
|
||||||
return GLRenderer->mLights->UploadLights(data);
|
return GLRenderer->mLights->UploadLights(data);
|
||||||
|
@ -312,6 +303,12 @@ void FDrawInfo::SetDepthMask(bool on)
|
||||||
glDepthMask(on);
|
glDepthMask(on);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FDrawInfo::SetDepthFunc(int func)
|
||||||
|
{
|
||||||
|
static int df2gl[] = { GL_LESS, GL_LEQUAL, GL_ALWAYS };
|
||||||
|
glDepthFunc(df2gl[func]);
|
||||||
|
}
|
||||||
|
|
||||||
void FDrawInfo::EnableDrawBufferAttachments(bool on)
|
void FDrawInfo::EnableDrawBufferAttachments(bool on)
|
||||||
{
|
{
|
||||||
gl_RenderState.EnableDrawBuffers(on? gl_RenderState.GetPassDrawBufferCount() : 1);
|
gl_RenderState.EnableDrawBuffers(on? gl_RenderState.GetPassDrawBufferCount() : 1);
|
||||||
|
|
|
@ -30,7 +30,6 @@ enum DrawListType
|
||||||
enum Drawpasses
|
enum Drawpasses
|
||||||
{
|
{
|
||||||
GLPASS_ALL, // Main pass with dynamic lights
|
GLPASS_ALL, // Main pass with dynamic lights
|
||||||
GLPASS_DECALS, // Draws a decal
|
|
||||||
GLPASS_TRANSLUCENT, // Draws translucent objects
|
GLPASS_TRANSLUCENT, // Draws translucent objects
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,14 +37,12 @@ struct FDrawInfo : public HWDrawInfo
|
||||||
{
|
{
|
||||||
HWDrawList drawlists[GLDL_TYPES];
|
HWDrawList drawlists[GLDL_TYPES];
|
||||||
TArray<HUDSprite> hudsprites; // These may just be stored by value.
|
TArray<HUDSprite> hudsprites; // These may just be stored by value.
|
||||||
TArray<GLDecal *> decals[2]; // the second slot is for mirrors which get rendered in a separate pass.
|
|
||||||
int vpIndex;
|
int vpIndex;
|
||||||
|
|
||||||
void ApplyVPUniforms() override;
|
void ApplyVPUniforms() override;
|
||||||
|
|
||||||
void AddWall(GLWall *wall) override;
|
void AddWall(GLWall *wall) override;
|
||||||
void AddMirrorSurface(GLWall *w) override;
|
void AddMirrorSurface(GLWall *w) override;
|
||||||
GLDecal *AddDecal(bool onmirror) override;
|
|
||||||
void AddPortal(GLWall *w, int portaltype) override;
|
void AddPortal(GLWall *w, int portaltype) override;
|
||||||
void AddFlat(GLFlat *flat, bool fog) override;
|
void AddFlat(GLFlat *flat, bool fog) override;
|
||||||
void AddSprite(GLSprite *sprite, bool translucent) override;
|
void AddSprite(GLSprite *sprite, bool translucent) override;
|
||||||
|
@ -57,18 +54,11 @@ struct FDrawInfo : public HWDrawInfo
|
||||||
void Draw(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) override;
|
void Draw(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) override;
|
||||||
void DrawIndexed(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) override;
|
void DrawIndexed(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) override;
|
||||||
void SetDepthMask(bool on) override;
|
void SetDepthMask(bool on) override;
|
||||||
|
void SetDepthFunc(int func) override;
|
||||||
void EnableDrawBufferAttachments(bool on) override;
|
void EnableDrawBufferAttachments(bool on) override;
|
||||||
|
|
||||||
void StartScene();
|
void StartScene();
|
||||||
|
|
||||||
// Wall drawer
|
|
||||||
void RenderWall(GLWall *wall, FRenderState &state, int textured);
|
|
||||||
void RenderFogBoundary(GLWall *wall, FRenderState &state);
|
|
||||||
void RenderMirrorSurface(GLWall *wall, FRenderState &state);
|
|
||||||
void RenderTranslucentWall(GLWall *wall, FRenderState &state);
|
|
||||||
void RenderTexturedWall(GLWall *wall, FRenderState &state, int rflags);
|
|
||||||
void DrawWall(GLWall *wall, int pass) override;
|
|
||||||
|
|
||||||
// Sprite drawer
|
// Sprite drawer
|
||||||
void DrawSprite(GLSprite *sprite, int pass);
|
void DrawSprite(GLSprite *sprite, int pass);
|
||||||
void DrawPSprite(HUDSprite *huds);
|
void DrawPSprite(HUDSprite *huds);
|
||||||
|
|
|
@ -173,7 +173,7 @@ void FDrawInfo::RenderScene(int recursion)
|
||||||
|
|
||||||
gl_RenderState.EnableTexture(gl_texture);
|
gl_RenderState.EnableTexture(gl_texture);
|
||||||
gl_RenderState.EnableBrightmap(true);
|
gl_RenderState.EnableBrightmap(true);
|
||||||
drawlists[GLDL_PLAINWALLS].DrawWalls(this, pass);
|
drawlists[GLDL_PLAINWALLS].DrawWalls(this, gl_RenderState, false);
|
||||||
drawlists[GLDL_PLAINFLATS].DrawFlats(this, gl_RenderState, false);
|
drawlists[GLDL_PLAINFLATS].DrawFlats(this, gl_RenderState, false);
|
||||||
|
|
||||||
|
|
||||||
|
@ -184,17 +184,15 @@ void FDrawInfo::RenderScene(int recursion)
|
||||||
gl_RenderState.SetTextureMode(TM_STENCIL);
|
gl_RenderState.SetTextureMode(TM_STENCIL);
|
||||||
}
|
}
|
||||||
gl_RenderState.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
|
gl_RenderState.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
|
||||||
drawlists[GLDL_MASKEDWALLS].DrawWalls(this, pass);
|
drawlists[GLDL_MASKEDWALLS].DrawWalls(this, gl_RenderState, false);
|
||||||
drawlists[GLDL_MASKEDFLATS].DrawFlats(this, gl_RenderState, false);
|
drawlists[GLDL_MASKEDFLATS].DrawFlats(this, gl_RenderState, false);
|
||||||
|
|
||||||
// Part 3: masked geometry with polygon offset. This list is empty most of the time so only waste time on it when in use.
|
// Part 3: masked geometry with polygon offset. This list is empty most of the time so only waste time on it when in use.
|
||||||
if (drawlists[GLDL_MASKEDWALLSOFS].Size() > 0)
|
if (drawlists[GLDL_MASKEDWALLSOFS].Size() > 0)
|
||||||
{
|
{
|
||||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
gl_RenderState.SetDepthBias(-1, -128);
|
||||||
glPolygonOffset(-1.0f, -128.0f);
|
drawlists[GLDL_MASKEDWALLSOFS].DrawWalls(this, gl_RenderState, false);
|
||||||
drawlists[GLDL_MASKEDWALLSOFS].DrawWalls(this, pass);
|
gl_RenderState.ClearDepthBias();
|
||||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
|
||||||
glPolygonOffset(0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
drawlists[GLDL_MODELS].Draw(this, gl_RenderState, false, pass);
|
drawlists[GLDL_MODELS].Draw(this, gl_RenderState, false, pass);
|
||||||
|
@ -203,10 +201,8 @@ void FDrawInfo::RenderScene(int recursion)
|
||||||
|
|
||||||
// Part 4: Draw decals (not a real pass)
|
// Part 4: Draw decals (not a real pass)
|
||||||
glDepthFunc(GL_LEQUAL);
|
glDepthFunc(GL_LEQUAL);
|
||||||
glDepthMask(false);
|
DrawDecals(gl_RenderState, Decals[0]);
|
||||||
DrawDecals(gl_RenderState, decals[0]);
|
|
||||||
|
|
||||||
glDepthMask(true);
|
|
||||||
RenderAll.Unclock();
|
RenderAll.Unclock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,8 +70,6 @@ void gl_SetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend
|
||||||
|
|
||||||
void FDrawInfo::DrawSprite(GLSprite *sprite, int pass)
|
void FDrawInfo::DrawSprite(GLSprite *sprite, int pass)
|
||||||
{
|
{
|
||||||
if (pass == GLPASS_DECALS) return;
|
|
||||||
|
|
||||||
auto RenderStyle = sprite->RenderStyle;
|
auto RenderStyle = sprite->RenderStyle;
|
||||||
|
|
||||||
bool additivefog = false;
|
bool additivefog = false;
|
||||||
|
|
|
@ -40,231 +40,6 @@
|
||||||
|
|
||||||
EXTERN_CVAR(Bool, gl_seamless)
|
EXTERN_CVAR(Bool, gl_seamless)
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// General purpose wall rendering function
|
|
||||||
// everything goes through here
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FDrawInfo::RenderWall(GLWall *wall, FRenderState &state, int textured)
|
|
||||||
{
|
|
||||||
assert(wall->vertcount > 0);
|
|
||||||
state.SetLightIndex(wall->dynlightindex);
|
|
||||||
Draw(DT_TriangleFan, gl_RenderState, wall->vertindex, wall->vertcount);
|
|
||||||
vertexcount += wall->vertcount;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FDrawInfo::RenderFogBoundary(GLWall *wall, FRenderState &state)
|
|
||||||
{
|
|
||||||
if (gl_fogmode && !isFullbrightScene())
|
|
||||||
{
|
|
||||||
int rel = wall->rellight + getExtraLight();
|
|
||||||
EnableDrawBufferAttachments(false);
|
|
||||||
state.SetFog(wall->lightlevel, rel, false, &wall->Colormap, false);
|
|
||||||
state.SetEffect(EFF_FOGBOUNDARY);
|
|
||||||
state.AlphaFunc(Alpha_GEqual, 0.f);
|
|
||||||
state.SetDepthBias(-1, -128);
|
|
||||||
RenderWall(wall, state, GLWall::RWF_BLANK);
|
|
||||||
state.ClearDepthBias();
|
|
||||||
state.SetEffect(EFF_NONE);
|
|
||||||
EnableDrawBufferAttachments(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
void FDrawInfo::RenderMirrorSurface(GLWall *wall, FRenderState &state)
|
|
||||||
{
|
|
||||||
if (!TexMan.mirrorTexture.isValid()) return;
|
|
||||||
|
|
||||||
// we use texture coordinates and texture matrix to pass the normal stuff to the shader so that the default vertex buffer format can be used as is.
|
|
||||||
state.EnableTextureMatrix(true);
|
|
||||||
|
|
||||||
// Use sphere mapping for this
|
|
||||||
state.SetEffect(EFF_SPHEREMAP);
|
|
||||||
|
|
||||||
state.SetColor(wall->lightlevel, 0, isFullbrightScene(), wall->Colormap ,0.1f);
|
|
||||||
state.SetFog(wall->lightlevel, 0, isFullbrightScene(), &wall->Colormap, true);
|
|
||||||
state.SetRenderStyle(STYLE_Add);
|
|
||||||
state.AlphaFunc(Alpha_Greater,0);
|
|
||||||
glDepthFunc(GL_LEQUAL);
|
|
||||||
|
|
||||||
FMaterial * pat=FMaterial::ValidateTexture(TexMan.mirrorTexture, false, false);
|
|
||||||
gl_RenderState.ApplyMaterial(pat, CLAMP_NONE, 0, -1);
|
|
||||||
|
|
||||||
wall->flags &= ~GLWall::GLWF_GLOW;
|
|
||||||
RenderWall(wall, state, GLWall::RWF_BLANK);
|
|
||||||
|
|
||||||
state.EnableTextureMatrix(false);
|
|
||||||
state.SetEffect(EFF_NONE);
|
|
||||||
|
|
||||||
// Restore the defaults for the translucent pass
|
|
||||||
state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
|
|
||||||
glDepthFunc(GL_LESS);
|
|
||||||
|
|
||||||
// This is drawn in the translucent pass which is done after the decal pass
|
|
||||||
// As a result the decals have to be drawn here, right after the wall they are on,
|
|
||||||
// because the depth buffer won't get set by translucent items.
|
|
||||||
if (wall->seg->sidedef->AttachedDecals)
|
|
||||||
{
|
|
||||||
wall->DrawDecalsForMirror(this, gl_RenderState, decals[1]);
|
|
||||||
}
|
|
||||||
state.SetRenderStyle(STYLE_Translucent);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FDrawInfo::RenderTexturedWall(GLWall *wall, FRenderState &state, int rflags)
|
|
||||||
{
|
|
||||||
int tmode = state.GetTextureMode();
|
|
||||||
int rel = wall->rellight + getExtraLight();
|
|
||||||
|
|
||||||
if (wall->flags & GLWall::GLWF_GLOW)
|
|
||||||
{
|
|
||||||
state.EnableGlow(true);
|
|
||||||
state.SetGlowParams(wall->topglowcolor, wall->bottomglowcolor);
|
|
||||||
}
|
|
||||||
state.SetGlowPlanes(wall->topplane, wall->bottomplane);
|
|
||||||
state.SetMaterial(wall->gltexture, wall->flags & 3, 0, -1);
|
|
||||||
|
|
||||||
if (wall->type == RENDERWALL_M2SNF)
|
|
||||||
{
|
|
||||||
if (wall->flags & GLWall::GLWF_CLAMPY)
|
|
||||||
{
|
|
||||||
if (tmode == TM_NORMAL) state.SetTextureMode(TM_CLAMPY);
|
|
||||||
}
|
|
||||||
SetFog(255, 0, nullptr, false);
|
|
||||||
}
|
|
||||||
state.SetObjectColor(wall->seg->frontsector->SpecialColors[sector_t::walltop] | 0xff000000);
|
|
||||||
state.SetObjectColor2(wall->seg->frontsector->SpecialColors[sector_t::wallbottom] | 0xff000000);
|
|
||||||
|
|
||||||
float absalpha = fabsf(wall->alpha);
|
|
||||||
if (wall->lightlist == nullptr)
|
|
||||||
{
|
|
||||||
if (wall->type != RENDERWALL_M2SNF) SetFog(wall->lightlevel, rel, &wall->Colormap, wall->RenderStyle == STYLE_Add);
|
|
||||||
SetColor(wall->lightlevel, rel, wall->Colormap, absalpha);
|
|
||||||
RenderWall(wall, state, rflags);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
state.EnableSplit(true);
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < wall->lightlist->Size(); i++)
|
|
||||||
{
|
|
||||||
secplane_t &lowplane = i == (*wall->lightlist).Size() - 1 ? wall->bottomplane : (*wall->lightlist)[i + 1].plane;
|
|
||||||
// this must use the exact same calculation method as GLWall::Process etc.
|
|
||||||
float low1 = lowplane.ZatPoint(wall->vertexes[0]);
|
|
||||||
float low2 = lowplane.ZatPoint(wall->vertexes[1]);
|
|
||||||
|
|
||||||
if (low1 < wall->ztop[0] || low2 < wall->ztop[1])
|
|
||||||
{
|
|
||||||
int thisll = (*wall->lightlist)[i].caster != NULL ? hw_ClampLight(*(*wall->lightlist)[i].p_lightlevel) : wall->lightlevel;
|
|
||||||
FColormap thiscm;
|
|
||||||
thiscm.FadeColor = wall->Colormap.FadeColor;
|
|
||||||
thiscm.FogDensity = wall->Colormap.FogDensity;
|
|
||||||
thiscm.CopyFrom3DLight(&(*wall->lightlist)[i]);
|
|
||||||
state.SetColor(thisll, rel, false, thiscm, absalpha);
|
|
||||||
if (wall->type != RENDERWALL_M2SNF) state.SetFog(thisll, rel, false, &thiscm, wall->RenderStyle == STYLE_Add);
|
|
||||||
state.SetSplitPlanes((*wall->lightlist)[i].plane, lowplane);
|
|
||||||
RenderWall(wall, state, rflags);
|
|
||||||
}
|
|
||||||
if (low1 <= wall->zbottom[0] && low2 <= wall->zbottom[1]) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.EnableSplit(false);
|
|
||||||
}
|
|
||||||
state.SetObjectColor(0xffffffff);
|
|
||||||
state.SetObjectColor2(0);
|
|
||||||
state.SetTextureMode(tmode);
|
|
||||||
state.EnableGlow(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FDrawInfo::RenderTranslucentWall(GLWall *wall, FRenderState &state)
|
|
||||||
{
|
|
||||||
state.SetRenderStyle(wall->RenderStyle);
|
|
||||||
if (wall->gltexture)
|
|
||||||
{
|
|
||||||
if (!wall->gltexture->tex->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
|
|
||||||
else state.AlphaFunc(Alpha_GEqual, 0.f);
|
|
||||||
RenderTexturedWall(wall, state, GLWall::RWF_TEXTURED | GLWall::RWF_NOSPLIT);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
state.AlphaFunc(Alpha_GEqual, 0.f);
|
|
||||||
state.SetColor(wall->lightlevel, 0, false, wall->Colormap, fabsf(wall->alpha));
|
|
||||||
state.SetFog(wall->lightlevel, 0, false, &wall->Colormap, wall->RenderStyle == STYLE_Add);
|
|
||||||
state.EnableTexture(false);
|
|
||||||
RenderWall(wall, state, GLWall::RWF_NOSPLIT);
|
|
||||||
state.EnableTexture(true);
|
|
||||||
}
|
|
||||||
state.SetRenderStyle(STYLE_Translucent);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
void FDrawInfo::DrawWall(GLWall *wall, int pass)
|
|
||||||
{
|
|
||||||
FRenderState &state = gl_RenderState;
|
|
||||||
if (screen->BuffersArePersistent())
|
|
||||||
{
|
|
||||||
if (level.HasDynamicLights && !isFullbrightScene() && wall->gltexture != nullptr)
|
|
||||||
{
|
|
||||||
wall->SetupLights(this, lightdata);
|
|
||||||
}
|
|
||||||
wall->MakeVertices(this, !!(wall->flags & GLWall::GLWF_TRANSLUCENT));
|
|
||||||
}
|
|
||||||
|
|
||||||
gl_RenderState.SetNormal(wall->glseg.Normal());
|
|
||||||
switch (pass)
|
|
||||||
{
|
|
||||||
case GLPASS_ALL:
|
|
||||||
RenderTexturedWall(wall, state, GLWall::RWF_TEXTURED);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GLPASS_TRANSLUCENT:
|
|
||||||
|
|
||||||
switch (wall->type)
|
|
||||||
{
|
|
||||||
case RENDERWALL_MIRRORSURFACE:
|
|
||||||
RenderMirrorSurface(wall, state);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RENDERWALL_FOGBOUNDARY:
|
|
||||||
RenderFogBoundary(wall, state);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
RenderTranslucentWall(wall, state);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
|
@ -132,6 +132,7 @@ void GLDecal::DrawDecal(HWDrawInfo *di, FRenderState &state)
|
||||||
void HWDrawInfo::DrawDecals(FRenderState &state, TArray<GLDecal *> &decals)
|
void HWDrawInfo::DrawDecals(FRenderState &state, TArray<GLDecal *> &decals)
|
||||||
{
|
{
|
||||||
side_t *wall = nullptr;
|
side_t *wall = nullptr;
|
||||||
|
SetDepthMask(false);
|
||||||
state.SetDepthBias(-1, -128);
|
state.SetDepthBias(-1, -128);
|
||||||
for (auto gldecal : decals)
|
for (auto gldecal : decals)
|
||||||
{
|
{
|
||||||
|
@ -153,6 +154,7 @@ void HWDrawInfo::DrawDecals(FRenderState &state, TArray<GLDecal *> &decals)
|
||||||
state.EnableSplit(false);
|
state.EnableSplit(false);
|
||||||
state.ClearDepthBias();
|
state.ClearDepthBias();
|
||||||
state.SetTextureMode(TM_NORMAL);
|
state.SetTextureMode(TM_NORMAL);
|
||||||
|
SetDepthMask(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "hw_fakeflat.h"
|
#include "hw_fakeflat.h"
|
||||||
#include "hw_drawinfo.h"
|
#include "hw_drawinfo.h"
|
||||||
#include "hw_portal.h"
|
#include "hw_portal.h"
|
||||||
|
#include "hw_drawlist.h"
|
||||||
#include "hwrenderer/utility/hw_clock.h"
|
#include "hwrenderer/utility/hw_clock.h"
|
||||||
#include "hwrenderer/utility/hw_cvars.h"
|
#include "hwrenderer/utility/hw_cvars.h"
|
||||||
|
|
||||||
|
@ -94,6 +95,9 @@ void HWDrawInfo::ClearBuffers()
|
||||||
memset(&ss_renderflags[0], 0, level.subsectors.Size() * sizeof(ss_renderflags[0]));
|
memset(&ss_renderflags[0], 0, level.subsectors.Size() * sizeof(ss_renderflags[0]));
|
||||||
memset(&no_renderflags[0], 0, level.nodes.Size() * sizeof(no_renderflags[0]));
|
memset(&no_renderflags[0], 0, level.nodes.Size() * sizeof(no_renderflags[0]));
|
||||||
|
|
||||||
|
Decals[0].Clear();
|
||||||
|
Decals[1].Clear();
|
||||||
|
|
||||||
mClipPortal = nullptr;
|
mClipPortal = nullptr;
|
||||||
mCurrentPortal = nullptr;
|
mCurrentPortal = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -282,3 +286,17 @@ void HWViewpointUniforms::SetDefaults()
|
||||||
mShadowmapFilter = gl_shadowmap_filter;
|
mShadowmapFilter = gl_shadowmap_filter;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
GLDecal *HWDrawInfo::AddDecal(bool onmirror)
|
||||||
|
{
|
||||||
|
auto decal = (GLDecal*)RenderDataAllocator.Alloc(sizeof(GLDecal));
|
||||||
|
Decals[onmirror ? 1 : 0].Push(decal);
|
||||||
|
return decal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,13 @@ enum EDrawType
|
||||||
DT_TriangleStrip = 4
|
DT_TriangleStrip = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum EDepthFunc
|
||||||
|
{
|
||||||
|
DF_Less,
|
||||||
|
DF_LEqual,
|
||||||
|
DF_Always
|
||||||
|
};
|
||||||
|
|
||||||
struct FSectorPortalGroup;
|
struct FSectorPortalGroup;
|
||||||
struct FLinePortalSpan;
|
struct FLinePortalSpan;
|
||||||
struct FFlatVertex;
|
struct FFlatVertex;
|
||||||
|
@ -130,6 +137,7 @@ struct HWDrawInfo
|
||||||
FRenderViewpoint Viewpoint;
|
FRenderViewpoint Viewpoint;
|
||||||
HWViewpointUniforms VPUniforms; // per-viewpoint uniform state
|
HWViewpointUniforms VPUniforms; // per-viewpoint uniform state
|
||||||
TArray<IPortal *> Portals;
|
TArray<IPortal *> Portals;
|
||||||
|
TArray<GLDecal *> Decals[2]; // the second slot is for mirrors which get rendered in a separate pass.
|
||||||
|
|
||||||
TArray<MissingTextureInfo> MissingUpperTextures;
|
TArray<MissingTextureInfo> MissingUpperTextures;
|
||||||
TArray<MissingTextureInfo> MissingLowerTextures;
|
TArray<MissingTextureInfo> MissingLowerTextures;
|
||||||
|
@ -286,7 +294,6 @@ public:
|
||||||
|
|
||||||
void DrawDecals(FRenderState &state, TArray<GLDecal *> &decals);
|
void DrawDecals(FRenderState &state, TArray<GLDecal *> &decals);
|
||||||
|
|
||||||
virtual void DrawWall(GLWall *wall, int pass) = 0;
|
|
||||||
virtual void DrawSprite(GLSprite *sprite, int pass) = 0;
|
virtual void DrawSprite(GLSprite *sprite, int pass) = 0;
|
||||||
|
|
||||||
void ProcessLowerMinisegs(TArray<seg_t *> &lowersegs);
|
void ProcessLowerMinisegs(TArray<seg_t *> &lowersegs);
|
||||||
|
@ -303,7 +310,7 @@ public:
|
||||||
virtual void ApplyVPUniforms() = 0;
|
virtual void ApplyVPUniforms() = 0;
|
||||||
virtual bool SetDepthClamp(bool on) = 0;
|
virtual bool SetDepthClamp(bool on) = 0;
|
||||||
|
|
||||||
virtual GLDecal *AddDecal(bool onmirror) = 0;
|
GLDecal *AddDecal(bool onmirror);
|
||||||
virtual std::pair<FFlatVertex *, unsigned int> AllocVertices(unsigned int count) = 0;
|
virtual std::pair<FFlatVertex *, unsigned int> AllocVertices(unsigned int count) = 0;
|
||||||
|
|
||||||
virtual void Draw(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) = 0;
|
virtual void Draw(EDrawType dt, FRenderState &state, int index, int count, bool apply = true) = 0;
|
||||||
|
@ -311,6 +318,7 @@ public:
|
||||||
|
|
||||||
// Immediate render state change commands. These only change infrequently and should not clutter the render state.
|
// Immediate render state change commands. These only change infrequently and should not clutter the render state.
|
||||||
virtual void SetDepthMask(bool on) = 0;
|
virtual void SetDepthMask(bool on) = 0;
|
||||||
|
virtual void SetDepthFunc(int func) = 0;
|
||||||
virtual void EnableDrawBufferAttachments(bool on) = 0;
|
virtual void EnableDrawBufferAttachments(bool on) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -788,7 +788,7 @@ void HWDrawList::DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, i
|
||||||
{
|
{
|
||||||
GLWall * w= walls[drawitems[i].index];
|
GLWall * w= walls[drawitems[i].index];
|
||||||
RenderWall.Clock();
|
RenderWall.Clock();
|
||||||
di->DrawWall(w, pass);
|
w->DrawWall(di, state, translucent);
|
||||||
RenderWall.Unclock();
|
RenderWall.Unclock();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -822,12 +822,12 @@ void HWDrawList::Draw(HWDrawInfo *di, FRenderState &state, bool translucent, int
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
void HWDrawList::DrawWalls(HWDrawInfo *di, int pass)
|
void HWDrawList::DrawWalls(HWDrawInfo *di, FRenderState &state, bool translucent)
|
||||||
{
|
{
|
||||||
RenderWall.Clock();
|
RenderWall.Clock();
|
||||||
for (auto &item : drawitems)
|
for (auto &item : drawitems)
|
||||||
{
|
{
|
||||||
di->DrawWall(walls[item.index], pass);
|
walls[item.index]->DrawWall(di, state, translucent);
|
||||||
}
|
}
|
||||||
RenderWall.Unclock();
|
RenderWall.Unclock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ public:
|
||||||
|
|
||||||
void DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, int pass, int i, bool trans);
|
void DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, int pass, int i, bool trans);
|
||||||
void Draw(HWDrawInfo *di, FRenderState &state, bool translucent, int pass, bool trans = false);
|
void Draw(HWDrawInfo *di, FRenderState &state, bool translucent, int pass, bool trans = false);
|
||||||
void DrawWalls(HWDrawInfo *di, int pass);
|
void DrawWalls(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||||
void DrawFlats(HWDrawInfo *di, FRenderState &state, bool translucent);
|
void DrawFlats(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||||
|
|
||||||
HWDrawList * next;
|
HWDrawList * next;
|
||||||
|
|
|
@ -263,6 +263,13 @@ public:
|
||||||
|
|
||||||
int CountVertices();
|
int CountVertices();
|
||||||
|
|
||||||
|
void RenderWall(HWDrawInfo *di, FRenderState &state, int textured);
|
||||||
|
void RenderFogBoundary(HWDrawInfo *di, FRenderState &state);
|
||||||
|
void RenderMirrorSurface(HWDrawInfo *di, FRenderState &state);
|
||||||
|
void RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags);
|
||||||
|
void RenderTranslucentWall(HWDrawInfo *di, FRenderState &state);
|
||||||
|
void DrawDecalsForMirror(HWDrawInfo *di, FRenderState &state, TArray<GLDecal *> &decals);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLWall() {}
|
GLWall() {}
|
||||||
|
|
||||||
|
@ -285,7 +292,7 @@ public:
|
||||||
return -((y-glseg.y1)*(glseg.x2-glseg.x1)-(x-glseg.x1)*(glseg.y2-glseg.y1));
|
return -((y-glseg.y1)*(glseg.x2-glseg.x1)-(x-glseg.x1)*(glseg.y2-glseg.y1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawDecalsForMirror(HWDrawInfo *di, FRenderState &state, TArray<GLDecal *> &decals);
|
void DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,227 @@
|
||||||
#include "hwrenderer/scene/hw_drawinfo.h"
|
#include "hwrenderer/scene/hw_drawinfo.h"
|
||||||
#include "hwrenderer/scene/hw_drawstructs.h"
|
#include "hwrenderer/scene/hw_drawstructs.h"
|
||||||
#include "hwrenderer/scene/hw_portal.h"
|
#include "hwrenderer/scene/hw_portal.h"
|
||||||
|
#include "hw_renderstate.h"
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// General purpose wall rendering function
|
||||||
|
// everything goes through here
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void GLWall::RenderWall(HWDrawInfo *di, FRenderState &state, int textured)
|
||||||
|
{
|
||||||
|
assert(vertcount > 0);
|
||||||
|
state.SetLightIndex(dynlightindex);
|
||||||
|
di->Draw(DT_TriangleFan, state, vertindex, vertcount);
|
||||||
|
vertexcount += vertcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void GLWall::RenderFogBoundary(HWDrawInfo *di, FRenderState &state)
|
||||||
|
{
|
||||||
|
if (gl_fogmode && !di->isFullbrightScene())
|
||||||
|
{
|
||||||
|
int rel = rellight + getExtraLight();
|
||||||
|
di->EnableDrawBufferAttachments(false);
|
||||||
|
state.SetFog(lightlevel, rel, false, &Colormap, false);
|
||||||
|
state.SetEffect(EFF_FOGBOUNDARY);
|
||||||
|
state.AlphaFunc(Alpha_GEqual, 0.f);
|
||||||
|
state.SetDepthBias(-1, -128);
|
||||||
|
RenderWall(di, state, GLWall::RWF_BLANK);
|
||||||
|
state.ClearDepthBias();
|
||||||
|
state.SetEffect(EFF_NONE);
|
||||||
|
di->EnableDrawBufferAttachments(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
void GLWall::RenderMirrorSurface(HWDrawInfo *di, FRenderState &state)
|
||||||
|
{
|
||||||
|
if (!TexMan.mirrorTexture.isValid()) return;
|
||||||
|
|
||||||
|
di->SetDepthFunc(DF_LEqual);
|
||||||
|
|
||||||
|
// we use texture coordinates and texture matrix to pass the normal stuff to the shader so that the default vertex buffer format can be used as is.
|
||||||
|
state.EnableTextureMatrix(true);
|
||||||
|
|
||||||
|
// Use sphere mapping for this
|
||||||
|
state.SetEffect(EFF_SPHEREMAP);
|
||||||
|
state.SetColor(lightlevel, 0, di->isFullbrightScene(), Colormap, 0.1f);
|
||||||
|
state.SetFog(lightlevel, 0, di->isFullbrightScene(), &Colormap, true);
|
||||||
|
state.SetRenderStyle(STYLE_Add);
|
||||||
|
state.AlphaFunc(Alpha_Greater, 0);
|
||||||
|
|
||||||
|
FMaterial * pat = FMaterial::ValidateTexture(TexMan.mirrorTexture, false, false);
|
||||||
|
state.SetMaterial(pat, CLAMP_NONE, 0, -1);
|
||||||
|
|
||||||
|
flags &= ~GLWall::GLWF_GLOW;
|
||||||
|
RenderWall(di, state, GLWall::RWF_BLANK);
|
||||||
|
|
||||||
|
state.EnableTextureMatrix(false);
|
||||||
|
state.SetEffect(EFF_NONE);
|
||||||
|
state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
|
||||||
|
|
||||||
|
di->SetDepthFunc(DF_Less);
|
||||||
|
|
||||||
|
// This is drawn in the translucent pass which is done after the decal pass
|
||||||
|
// As a result the decals have to be drawn here, right after the wall they are on,
|
||||||
|
// because the depth buffer won't get set by translucent items.
|
||||||
|
if (seg->sidedef->AttachedDecals)
|
||||||
|
{
|
||||||
|
DrawDecalsForMirror(di, state, di->Decals[1]);
|
||||||
|
}
|
||||||
|
state.SetRenderStyle(STYLE_Translucent);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void GLWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
|
||||||
|
{
|
||||||
|
int tmode = state.GetTextureMode();
|
||||||
|
int rel = rellight + getExtraLight();
|
||||||
|
|
||||||
|
if (flags & GLWall::GLWF_GLOW)
|
||||||
|
{
|
||||||
|
state.EnableGlow(true);
|
||||||
|
state.SetGlowParams(topglowcolor, bottomglowcolor);
|
||||||
|
}
|
||||||
|
state.SetGlowPlanes(topplane, bottomplane);
|
||||||
|
state.SetMaterial(gltexture, flags & 3, 0, -1);
|
||||||
|
|
||||||
|
if (type == RENDERWALL_M2SNF)
|
||||||
|
{
|
||||||
|
if (flags & GLWall::GLWF_CLAMPY)
|
||||||
|
{
|
||||||
|
if (tmode == TM_NORMAL) state.SetTextureMode(TM_CLAMPY);
|
||||||
|
}
|
||||||
|
state.SetFog(255, 0, di->isFullbrightScene(), nullptr, false);
|
||||||
|
}
|
||||||
|
state.SetObjectColor(seg->frontsector->SpecialColors[sector_t::walltop] | 0xff000000);
|
||||||
|
state.SetObjectColor2(seg->frontsector->SpecialColors[sector_t::wallbottom] | 0xff000000);
|
||||||
|
|
||||||
|
float absalpha = fabsf(alpha);
|
||||||
|
if (lightlist == nullptr)
|
||||||
|
{
|
||||||
|
if (type != RENDERWALL_M2SNF) state.SetFog(lightlevel, rel, di->isFullbrightScene(), &Colormap, RenderStyle == STYLE_Add);
|
||||||
|
state.SetColor(lightlevel, rel, di->isFullbrightScene(), Colormap, absalpha);
|
||||||
|
RenderWall(di, state, rflags);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state.EnableSplit(true);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < lightlist->Size(); i++)
|
||||||
|
{
|
||||||
|
secplane_t &lowplane = i == (*lightlist).Size() - 1 ? bottomplane : (*lightlist)[i + 1].plane;
|
||||||
|
// this must use the exact same calculation method as GLWall::Process etc.
|
||||||
|
float low1 = lowplane.ZatPoint(vertexes[0]);
|
||||||
|
float low2 = lowplane.ZatPoint(vertexes[1]);
|
||||||
|
|
||||||
|
if (low1 < ztop[0] || low2 < ztop[1])
|
||||||
|
{
|
||||||
|
int thisll = (*lightlist)[i].caster != NULL ? hw_ClampLight(*(*lightlist)[i].p_lightlevel) : lightlevel;
|
||||||
|
FColormap thiscm;
|
||||||
|
thiscm.FadeColor = Colormap.FadeColor;
|
||||||
|
thiscm.FogDensity = Colormap.FogDensity;
|
||||||
|
thiscm.CopyFrom3DLight(&(*lightlist)[i]);
|
||||||
|
state.SetColor(thisll, rel, false, thiscm, absalpha);
|
||||||
|
if (type != RENDERWALL_M2SNF) state.SetFog(thisll, rel, false, &thiscm, RenderStyle == STYLE_Add);
|
||||||
|
state.SetSplitPlanes((*lightlist)[i].plane, lowplane);
|
||||||
|
RenderWall(di, state, rflags);
|
||||||
|
}
|
||||||
|
if (low1 <= zbottom[0] && low2 <= zbottom[1]) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.EnableSplit(false);
|
||||||
|
}
|
||||||
|
state.SetObjectColor(0xffffffff);
|
||||||
|
state.SetObjectColor2(0);
|
||||||
|
state.SetTextureMode(tmode);
|
||||||
|
state.EnableGlow(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void GLWall::RenderTranslucentWall(HWDrawInfo *di, FRenderState &state)
|
||||||
|
{
|
||||||
|
state.SetRenderStyle(RenderStyle);
|
||||||
|
if (gltexture)
|
||||||
|
{
|
||||||
|
if (!gltexture->tex->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
|
||||||
|
else state.AlphaFunc(Alpha_GEqual, 0.f);
|
||||||
|
RenderTexturedWall(di, state, GLWall::RWF_TEXTURED | GLWall::RWF_NOSPLIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state.AlphaFunc(Alpha_GEqual, 0.f);
|
||||||
|
state.SetColor(lightlevel, 0, false, Colormap, fabsf(alpha));
|
||||||
|
state.SetFog(lightlevel, 0, false, &Colormap, RenderStyle == STYLE_Add);
|
||||||
|
state.EnableTexture(false);
|
||||||
|
RenderWall(di, state, GLWall::RWF_NOSPLIT);
|
||||||
|
state.EnableTexture(true);
|
||||||
|
}
|
||||||
|
state.SetRenderStyle(STYLE_Translucent);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
void GLWall::DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent)
|
||||||
|
{
|
||||||
|
if (screen->BuffersArePersistent())
|
||||||
|
{
|
||||||
|
if (level.HasDynamicLights && !di->isFullbrightScene() && gltexture != nullptr)
|
||||||
|
{
|
||||||
|
SetupLights(di, lightdata);
|
||||||
|
}
|
||||||
|
MakeVertices(di, !!(flags & GLWall::GLWF_TRANSLUCENT));
|
||||||
|
}
|
||||||
|
|
||||||
|
state.SetNormal(glseg.Normal());
|
||||||
|
if (!translucent)
|
||||||
|
{
|
||||||
|
RenderTexturedWall(di, state, GLWall::RWF_TEXTURED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case RENDERWALL_MIRRORSURFACE:
|
||||||
|
RenderMirrorSurface(di, state);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RENDERWALL_FOGBOUNDARY:
|
||||||
|
RenderFogBoundary(di, state);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
RenderTranslucentWall(di, state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue