- made the screen blend work for the software renderer.

It may use the same calculations as the hardware renderer but must use the 2D drawer for display.
It should be investigated if the hardware renderer can do this as well.
This commit is contained in:
Christoph Oelckers 2018-04-07 10:53:20 +02:00
parent b34d7f9e08
commit 211a7f2569
10 changed files with 49 additions and 28 deletions

View file

@ -108,12 +108,12 @@ CUSTOM_CVAR(Int,gl_fogmode,1,CVAR_ARCHIVE|CVAR_NOINITCALL)
void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblending,
int *tm, int *sb, int *db, int *be)
{
static int blendstyles[] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA };
static int blendstyles[] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, };
static int renderops[] = { 0, GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1 };
int srcblend = blendstyles[style.SrcAlpha&3];
int dstblend = blendstyles[style.DestAlpha&3];
int srcblend = blendstyles[style.SrcAlpha%STYLEALPHA_MAX];
int dstblend = blendstyles[style.DestAlpha%STYLEALPHA_MAX];
int blendequation = renderops[style.BlendOp&15];
int texturemode = drawopaque? TM_OPAQUE : TM_MODULATE;

View file

@ -560,7 +560,7 @@ void gl_FillScreen()
// Draws a blend over the entire view
//
//==========================================================================
void FGLRenderer::DrawBlend(sector_t * viewsector, bool FixedColormap, bool docolormap)
void FGLRenderer::DrawBlend(sector_t * viewsector, bool FixedColormap, bool docolormap, bool in2d)
{
float blend[4] = { 0,0,0,0 };
PalEntry blendv = 0;
@ -623,15 +623,22 @@ void FGLRenderer::DrawBlend(sector_t * viewsector, bool FixedColormap, bool doco
extra_blue = blendv.b / 255.0f;
// If this is a multiplicative blend do it separately and add the additive ones on top of it.
blendv = 0;
// black multiplicative blends are ignored
if (extra_red || extra_green || extra_blue)
{
gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO);
gl_RenderState.SetColor(extra_red, extra_green, extra_blue, 1.0f);
gl_FillScreen();
if (!in2d)
{
gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO);
gl_RenderState.SetColor(extra_red, extra_green, extra_blue, 1.0f);
gl_FillScreen();
}
else
{
screen->Dim(blendv, 1, 0, 0, screen->GetWidth(), screen->GetHeight(), &LegacyRenderStyles[STYLE_Multiply]);
}
}
blendv = 0;
}
else if (blendv.a)
{
@ -655,15 +662,22 @@ void FGLRenderer::DrawBlend(sector_t * viewsector, bool FixedColormap, bool doco
V_AddBlend(player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend);
}
gl_RenderState.SetTextureMode(TM_MODULATE);
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (blend[3]>0.0f)
if (!in2d)
{
gl_RenderState.SetColor(blend[0], blend[1], blend[2], blend[3]);
gl_FillScreen();
gl_RenderState.SetTextureMode(TM_MODULATE);
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (blend[3] > 0.0f)
{
gl_RenderState.SetColor(blend[0], blend[1], blend[2], blend[3]);
gl_FillScreen();
}
gl_RenderState.ResetColor();
gl_RenderState.EnableTexture(true);
}
else
{
screen->Dim(PalEntry(255, blend[0] * 255, blend[1] * 255, blend[2] * 255), blend[3], 0, 0, screen->GetWidth(), screen->GetHeight());
}
gl_RenderState.ResetColor();
gl_RenderState.EnableTexture(true);
}

View file

@ -193,7 +193,7 @@ public:
void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV);
void WriteSavePic(player_t *player, FileWriter *file, int width, int height);
void RenderView(player_t *player);
void DrawBlend(sector_t * viewsector, bool FixedColormap, bool docolormap);
void DrawBlend(sector_t * viewsector, bool FixedColormap, bool docolormap, bool in2d = false);
bool StartOffscreen();

View file

@ -123,5 +123,5 @@ void SWSceneDrawer::RenderView(player_t *player)
screen->Begin2D(false);
screen->DrawTexture(FBTexture, 0, 0, DTA_SpecialColormap, map, TAG_DONE);
SWRenderer->DrawRemainingPlayerSprites();
GLRenderer->DrawBlend(r_viewpoint.sector, !!map, swtruecolor);
GLRenderer->DrawBlend(r_viewpoint.sector, !!map, swtruecolor, true);
}

View file

@ -58,6 +58,7 @@ FRenderStyle LegacyRenderStyles[STYLE_Count] =
{ { STYLEOP_RevSub, STYLEALPHA_Src, STYLEALPHA_One, 0 } }, /* STYLE_Subtract*/
{ { STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_One, STYLEF_ColorIsFixed } }, /* STYLE_AddStencil */
{ { STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_One, STYLEF_RedIsAlpha | STYLEF_ColorIsFixed } }, /* STYLE_AddShaded */
{ { STYLEOP_Add, STYLEALPHA_InvDstCol, STYLEALPHA_Zero, 0 } }, /* STYLE_Multiply */
};
double GetAlpha(int type, double alpha)
@ -68,7 +69,7 @@ double GetAlpha(int type, double alpha)
case STYLEALPHA_One: return 1.;
case STYLEALPHA_Src: return alpha;
case STYLEALPHA_InvSrc: return 1. - alpha;
default: return 0;
default: return 0.5; // undeterminable
}
}

View file

@ -61,6 +61,7 @@ enum ERenderStyle
STYLE_Subtract, // Actually this is 'reverse subtract' but this is what normal people would expect by 'subtract'.
STYLE_AddStencil, // Fill image interior with alphacolor
STYLE_AddShaded, // Treat patch data as alpha values for alphacolor
STYLE_Multiply, // Multiply source with destination (HW renderer only.)
STYLE_Count
};
@ -87,6 +88,11 @@ enum ERenderAlpha
STYLEALPHA_One, // Blend factor is 1.0
STYLEALPHA_Src, // Blend factor is alpha
STYLEALPHA_InvSrc, // Blend factor is 1.0 - alpha
STYLEALPHA_SrcCol, // Blend factor is color (HWR only)
STYLEALPHA_InvSrcCol, // Blend factor is 1.0 - color (HWR only)
STYLEALPHA_DstCol, // Blend factor is dest. color (HWR only)
STYLEALPHA_InvDstCol, // Blend factor is 1.0 - dest. color (HWR only)
STYLEALPHA_MAX
};
enum ERenderFlags

View file

@ -435,14 +435,14 @@ void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FTexture *
//
//===========================================================================
void F2DDrawer::AddColorOnlyQuad(int x1, int y1, int w, int h, PalEntry color)
void F2DDrawer::AddColorOnlyQuad(int x1, int y1, int w, int h, PalEntry color, FRenderStyle *style)
{
RenderCommand dg;
dg.mType = DrawTypeTriangles;
dg.mVertCount = 4;
dg.mVertIndex = (int)mVertices.Reserve(4);
dg.mRenderStyle = LegacyRenderStyles[STYLE_Translucent];
dg.mRenderStyle = style? *style : LegacyRenderStyles[STYLE_Translucent];
auto ptr = &mVertices[dg.mVertIndex];
ptr->Set(x1, y1, 0, 0, 0, color); ptr++;
ptr->Set(x1, y1 + h, 0, 0, 0, color); ptr++;

View file

@ -122,7 +122,7 @@ public:
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel);
void AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin);
void AddColorOnlyQuad(int left, int top, int width, int height, PalEntry color);
void AddColorOnlyQuad(int left, int top, int width, int height, PalEntry color, FRenderStyle *style);
void AddDim(PalEntry color, float damount, int x1, int y1, int w, int h);
void AddClear(int left, int top, int right, int bottom, int palcolor, uint32_t color);

View file

@ -1106,7 +1106,7 @@ void DFrameBuffer::Clear(int left, int top, int right, int bottom, int palcolor,
{
color = GPalette.BaseColors[palcolor] | 0xff000000;
}
m2DDrawer.AddColorOnlyQuad(left, top, right - left, bottom - top, color | 0xFF000000);
m2DDrawer.AddColorOnlyQuad(left, top, right - left, bottom - top, color | 0xFF000000, nullptr);
}
DEFINE_ACTION_FUNCTION(_Screen, Clear)
@ -1131,7 +1131,7 @@ DEFINE_ACTION_FUNCTION(_Screen, Clear)
//
//==========================================================================
void DFrameBuffer::DoDim(PalEntry color, float amount, int x1, int y1, int w, int h)
void DFrameBuffer::DoDim(PalEntry color, float amount, int x1, int y1, int w, int h, FRenderStyle *style)
{
if (amount <= 0)
{
@ -1141,10 +1141,10 @@ void DFrameBuffer::DoDim(PalEntry color, float amount, int x1, int y1, int w, in
{
amount = 1;
}
m2DDrawer.AddColorOnlyQuad(x1, y1, w, h, color | (int(amount * 255) << 24));
m2DDrawer.AddColorOnlyQuad(x1, y1, w, h, color.d & 0xffffff | (int(amount * 255) << 24), style);
}
void DFrameBuffer::Dim(PalEntry color, float damount, int x1, int y1, int w, int h)
void DFrameBuffer::Dim(PalEntry color, float damount, int x1, int y1, int w, int h, FRenderStyle *style)
{
if (clipwidth >= 0 && clipheight >= 0)
{
@ -1164,7 +1164,7 @@ void DFrameBuffer::Dim(PalEntry color, float damount, int x1, int y1, int w, int
if (h > clipheight) h = clipheight;
if (h <= 0) return;
}
DoDim(color, damount, x1, y1, w, h);
DoDim(color, damount, x1, y1, w, h, style);
}
DEFINE_ACTION_FUNCTION(_Screen, Dim)

View file

@ -371,8 +371,8 @@ public:
void Clear2D() { m2DDrawer.Clear(); }
// Dim part of the canvas
void Dim(PalEntry color, float amount, int x1, int y1, int w, int h);
void DoDim(PalEntry color, float amount, int x1, int y1, int w, int h);
void Dim(PalEntry color, float amount, int x1, int y1, int w, int h, FRenderStyle *style = nullptr);
void DoDim(PalEntry color, float amount, int x1, int y1, int w, int h, FRenderStyle *style = nullptr);
// Fill an area with a texture
void FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin = false);