mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- added a software scene drawer to the GL renderer.
It still looks like shit and only works on the modern render path but at least the basics are working.
This commit is contained in:
parent
d474b849a5
commit
b34d7f9e08
32 changed files with 569 additions and 302 deletions
|
@ -852,6 +852,7 @@ set( FASTMATH_SOURCES
|
|||
gl/scene/gl_renderhacks.cpp
|
||||
gl/scene/gl_weapon.cpp
|
||||
gl/scene/gl_scene.cpp
|
||||
gl/scene/gl_swscene.cpp
|
||||
gl/scene/gl_sky.cpp
|
||||
gl/scene/gl_portal.cpp
|
||||
gl/scene/gl_walls_draw.cpp
|
||||
|
|
|
@ -794,23 +794,11 @@ void D_Display ()
|
|||
break;
|
||||
}
|
||||
|
||||
if (StatusBar != NULL)
|
||||
{
|
||||
float blend[4] = { 0, 0, 0, 0 };
|
||||
StatusBar->BlendView (blend);
|
||||
}
|
||||
screen->SetBlendingRect(viewwindowx, viewwindowy,
|
||||
viewwindowx + viewwidth, viewwindowy + viewheight);
|
||||
|
||||
// [ZZ] execute event hook that we just started the frame
|
||||
//E_RenderFrame();
|
||||
//
|
||||
screen->RenderView(&players[consoleplayer]);
|
||||
|
||||
screen->Begin2D(viewactive);
|
||||
// todo: These need to go into RenderView.
|
||||
//Renderer->DrawRemainingPlayerSprites();
|
||||
//screen->DrawBlendingRect();
|
||||
// returns with 2S mode set.
|
||||
if (automapactive)
|
||||
{
|
||||
AM_Drawer (hud_althud? viewheight : StatusBar->GetTopOfStatusbar());
|
||||
|
|
|
@ -196,6 +196,7 @@ enum class ETextureType : uint8_t
|
|||
SkinGraphic,
|
||||
Null,
|
||||
FirstDefined,
|
||||
SWCanvas,
|
||||
};
|
||||
|
||||
class FTextureID
|
||||
|
|
|
@ -405,7 +405,6 @@ public:
|
|||
void AttachToPlayer(player_t *player);
|
||||
DVector2 GetHUDScale() const;
|
||||
virtual void FlashCrosshair ();
|
||||
virtual void BlendView (float blend[4]);
|
||||
void NewGame ();
|
||||
virtual void ScreenSizeChanged ();
|
||||
void CallScreenSizeChanged();
|
||||
|
|
|
@ -95,10 +95,6 @@ extern int setblocks;
|
|||
FTexture *CrosshairImage;
|
||||
static int CrosshairNum;
|
||||
|
||||
// [RH] Base blending values (for e.g. underwater)
|
||||
int BaseBlendR, BaseBlendG, BaseBlendB;
|
||||
float BaseBlendA;
|
||||
|
||||
CVAR (Int, paletteflash, 0, CVAR_ARCHIVE)
|
||||
CVAR (Flag, pf_hexenweaps, paletteflash, PF_HEXENWEAPONS)
|
||||
CVAR (Flag, pf_poison, paletteflash, PF_POISON)
|
||||
|
@ -1196,26 +1192,6 @@ void DBaseStatusBar::DrawTopStuff (EHudState state)
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// BlendView
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DBaseStatusBar::BlendView (float blend[4])
|
||||
{
|
||||
// [Nash] Allow user to set blend intensity
|
||||
float cnt = (BaseBlendA * underwater_fade_scalar);
|
||||
|
||||
V_AddBlend (BaseBlendR / 255.f, BaseBlendG / 255.f, BaseBlendB / 255.f, cnt, blend);
|
||||
V_AddPlayerBlend(CPlayer, blend, 1.0f, 228);
|
||||
|
||||
player_t *player = (CPlayer->camera != NULL && CPlayer->camera->player != NULL) ? CPlayer->camera->player : CPlayer;
|
||||
V_AddBlend (player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend);
|
||||
|
||||
V_SetBlend ((int)(blend[0] * 255.0f), (int)(blend[1] * 255.0f),
|
||||
(int)(blend[2] * 255.0f), (int)(blend[3] * 256.0f));
|
||||
}
|
||||
|
||||
void DBaseStatusBar::DrawConsistancy () const
|
||||
{
|
||||
|
|
|
@ -208,7 +208,7 @@ static bool currentModelMatrixState;
|
|||
|
||||
void FRenderState::ApplyFixedFunction()
|
||||
{
|
||||
int thistm = mTextureMode == TM_MODULATE && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode;
|
||||
int thistm = mTextureMode == TM_MODULATE && (mTempTM == TM_OPAQUE || mSpecialEffect == EFF_SWQUAD) ? TM_OPAQUE : mTextureMode;
|
||||
if (thistm != ffTextureMode)
|
||||
{
|
||||
ffTextureMode = thistm;
|
||||
|
|
|
@ -169,9 +169,9 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
|
|||
|
||||
// and the second one for the fullscreen quad used for blend overlays.
|
||||
vbo_shadowdata[4].Set(0, 0, 0, 0, 0);
|
||||
vbo_shadowdata[5].Set(0, (float)height, 0, 0, 0);
|
||||
vbo_shadowdata[6].Set((float)width, 0, 0, 0, 0);
|
||||
vbo_shadowdata[7].Set((float)width, (float)height, 0, 0, 0);
|
||||
vbo_shadowdata[5].Set(0, (float)height, 0, 0, 1);
|
||||
vbo_shadowdata[6].Set((float)width, 0, 0, 1, 0);
|
||||
vbo_shadowdata[7].Set((float)width, (float)height, 0, 1, 1);
|
||||
|
||||
// and this is for the postprocessing copy operation
|
||||
vbo_shadowdata[8].Set(-1.0f, -1.0f, 0, 0.0f, 0.0f);
|
||||
|
@ -217,10 +217,10 @@ FFlatVertexBuffer::~FFlatVertexBuffer()
|
|||
void FFlatVertexBuffer::OutputResized(int width, int height)
|
||||
{
|
||||
vbo_shadowdata[4].Set(0, 0, 0, 0, 0);
|
||||
vbo_shadowdata[5].Set(0, (float)height, 0, 0, 0);
|
||||
vbo_shadowdata[6].Set((float)width, 0, 0, 0, 0);
|
||||
vbo_shadowdata[7].Set((float)width, (float)height, 0, 0, 0);
|
||||
|
||||
vbo_shadowdata[5].Set(0, (float)height, 0, 0, 1);
|
||||
vbo_shadowdata[6].Set((float)width, 0, 0, 1, 0);
|
||||
vbo_shadowdata[7].Set((float)width, (float)height, 0, 1, 1);
|
||||
|
||||
Map();
|
||||
memcpy(&map[4], &vbo_shadowdata[4], 4 * sizeof(FFlatVertex));
|
||||
Unmap();
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/scene/gl_scenedrawer.h"
|
||||
#include "gl/scene/gl_swscene.h"
|
||||
#include "gl/scene/gl_portal.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/shaders/gl_ambientshader.h"
|
||||
|
@ -75,6 +76,8 @@
|
|||
|
||||
EXTERN_CVAR(Int, screenblocks)
|
||||
EXTERN_CVAR(Bool, cl_capfps)
|
||||
EXTERN_CVAR(Float, underwater_fade_scalar)
|
||||
EXTERN_CVAR(Bool, swtruecolor)
|
||||
|
||||
CVAR(Bool, gl_scale_viewport, true, CVAR_ARCHIVE);
|
||||
extern bool NoInterpolateView;
|
||||
|
@ -206,6 +209,7 @@ FGLRenderer::~FGLRenderer()
|
|||
glBindVertexArray(0);
|
||||
glDeleteVertexArrays(1, &mVAOID);
|
||||
}
|
||||
if (swdrawer) delete swdrawer;
|
||||
if (mBuffers) delete mBuffers;
|
||||
if (mPresentShader) delete mPresentShader;
|
||||
if (mLinearDepthShader) delete mLinearDepthShader;
|
||||
|
@ -423,55 +427,63 @@ void FGLRenderer::EndOffscreen()
|
|||
// renders the view
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
extern int currentrenderer;
|
||||
|
||||
void FGLRenderer::RenderView(player_t* player)
|
||||
{
|
||||
// Todo: This needs to call the software renderer and process the returned image, if so desired.
|
||||
checkBenchActive();
|
||||
|
||||
gl_RenderState.SetVertexBuffer(mVBO);
|
||||
mVBO->Reset();
|
||||
|
||||
// reset statistics counters
|
||||
ResetProfilingData();
|
||||
|
||||
// Get this before everything else
|
||||
if (cl_capfps || r_NoInterpolate) r_viewpoint.TicFrac = 1.;
|
||||
else r_viewpoint.TicFrac = I_GetTimeFrac();
|
||||
|
||||
P_FindParticleSubsectors();
|
||||
|
||||
if (!gl.legacyMode) mLights->Clear();
|
||||
|
||||
// NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below.
|
||||
bool saved_niv = NoInterpolateView;
|
||||
NoInterpolateView = false;
|
||||
// prepare all camera textures that have been used in the last frame
|
||||
FCanvasTextureInfo::UpdateAll();
|
||||
NoInterpolateView = saved_niv;
|
||||
|
||||
|
||||
// now render the main view
|
||||
float fovratio;
|
||||
float ratio = r_viewwindow.WidescreenRatio;
|
||||
if (r_viewwindow.WidescreenRatio >= 1.3f)
|
||||
if (currentrenderer == 0)
|
||||
{
|
||||
fovratio = 1.333333f;
|
||||
if (swdrawer == nullptr) swdrawer = new SWSceneDrawer;
|
||||
swdrawer->RenderView(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
fovratio = ratio;
|
||||
checkBenchActive();
|
||||
|
||||
// reset statistics counters
|
||||
ResetProfilingData();
|
||||
|
||||
// Get this before everything else
|
||||
if (cl_capfps || r_NoInterpolate) r_viewpoint.TicFrac = 1.;
|
||||
else r_viewpoint.TicFrac = I_GetTimeFrac();
|
||||
|
||||
P_FindParticleSubsectors();
|
||||
|
||||
if (!gl.legacyMode) mLights->Clear();
|
||||
|
||||
// NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below.
|
||||
bool saved_niv = NoInterpolateView;
|
||||
NoInterpolateView = false;
|
||||
// prepare all camera textures that have been used in the last frame
|
||||
FCanvasTextureInfo::UpdateAll();
|
||||
NoInterpolateView = saved_niv;
|
||||
|
||||
|
||||
// now render the main view
|
||||
float fovratio;
|
||||
float ratio = r_viewwindow.WidescreenRatio;
|
||||
if (r_viewwindow.WidescreenRatio >= 1.3f)
|
||||
{
|
||||
fovratio = 1.333333f;
|
||||
}
|
||||
else
|
||||
{
|
||||
fovratio = ratio;
|
||||
}
|
||||
// Check if there's some lights. If not some code can be skipped.
|
||||
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
|
||||
mLightCount = ((it.Next()) != NULL);
|
||||
|
||||
GLSceneDrawer drawer;
|
||||
|
||||
drawer.SetFixedColormap(player);
|
||||
|
||||
mShadowMap.Update();
|
||||
sector_t * viewsector = drawer.RenderViewpoint(player->camera, NULL, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, true, true);
|
||||
}
|
||||
GLSceneDrawer drawer;
|
||||
|
||||
drawer.SetFixedColormap(player);
|
||||
|
||||
// Check if there's some lights. If not some code can be skipped.
|
||||
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
|
||||
mLightCount = ((it.Next()) != NULL);
|
||||
|
||||
mShadowMap.Update();
|
||||
sector_t * viewsector = drawer.RenderViewpoint(player->camera, NULL, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, true, true);
|
||||
|
||||
All.Unclock();
|
||||
}
|
||||
|
@ -534,6 +546,127 @@ void FGLRenderer::WriteSavePic(player_t *player, FileWriter *file, int width, in
|
|||
}
|
||||
|
||||
|
||||
void gl_FillScreen()
|
||||
{
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
// The fullscreen quad is stored at index 4 in the main vertex buffer.
|
||||
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Draws a blend over the entire view
|
||||
//
|
||||
//==========================================================================
|
||||
void FGLRenderer::DrawBlend(sector_t * viewsector, bool FixedColormap, bool docolormap)
|
||||
{
|
||||
float blend[4] = { 0,0,0,0 };
|
||||
PalEntry blendv = 0;
|
||||
float extra_red;
|
||||
float extra_green;
|
||||
float extra_blue;
|
||||
player_t *player = NULL;
|
||||
|
||||
if (players[consoleplayer].camera != NULL)
|
||||
{
|
||||
player = players[consoleplayer].camera->player;
|
||||
}
|
||||
|
||||
// don't draw sector based blends when an invulnerability colormap is active
|
||||
if (!FixedColormap)
|
||||
{
|
||||
if (!viewsector->e->XFloor.ffloors.Size())
|
||||
{
|
||||
if (viewsector->heightsec && !(viewsector->MoreFlags&SECF_IGNOREHEIGHTSEC))
|
||||
{
|
||||
auto s = viewsector->heightsec;
|
||||
blendv = s->floorplane.PointOnSide(r_viewpoint.Pos) < 0? s->bottommap : s->ceilingplane.PointOnSide(r_viewpoint.Pos) < 0 ? s->topmap : s->midmap;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TArray<lightlist_t> & lightlist = viewsector->e->XFloor.lightlist;
|
||||
|
||||
for (unsigned int i = 0; i < lightlist.Size(); i++)
|
||||
{
|
||||
double lightbottom;
|
||||
if (i < lightlist.Size() - 1)
|
||||
lightbottom = lightlist[i + 1].plane.ZatPoint(r_viewpoint.Pos);
|
||||
else
|
||||
lightbottom = viewsector->floorplane.ZatPoint(r_viewpoint.Pos);
|
||||
|
||||
if (lightbottom < r_viewpoint.Pos.Z && (!lightlist[i].caster || !(lightlist[i].caster->flags&FF_FADEWALLS)))
|
||||
{
|
||||
// 3d floor 'fog' is rendered as a blending value
|
||||
blendv = lightlist[i].blend;
|
||||
// If this is the same as the sector's it doesn't apply!
|
||||
if (blendv == viewsector->Colormap.FadeColor) blendv = 0;
|
||||
// a little hack to make this work for Legacy maps.
|
||||
if (blendv.a == 0 && blendv != 0) blendv.a = 128;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (blendv.a == 0 && docolormap)
|
||||
{
|
||||
blendv = R_BlendForColormap(blendv);
|
||||
}
|
||||
|
||||
if (blendv.a == 255)
|
||||
{
|
||||
|
||||
extra_red = blendv.r / 255.0f;
|
||||
extra_green = blendv.g / 255.0f;
|
||||
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();
|
||||
}
|
||||
}
|
||||
else if (blendv.a)
|
||||
{
|
||||
// [Nash] allow user to set blend intensity
|
||||
int cnt = blendv.a;
|
||||
cnt = (int)(cnt * underwater_fade_scalar);
|
||||
|
||||
V_AddBlend(blendv.r / 255.f, blendv.g / 255.f, blendv.b / 255.f, cnt / 255.0f, blend);
|
||||
}
|
||||
}
|
||||
|
||||
if (player)
|
||||
{
|
||||
V_AddPlayerBlend(player, blend, 0.5, 175);
|
||||
}
|
||||
|
||||
if (players[consoleplayer].camera != NULL)
|
||||
{
|
||||
// except for fadeto effects
|
||||
player_t *player = (players[consoleplayer].camera->player != NULL) ? players[consoleplayer].camera->player : &players[consoleplayer];
|
||||
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)
|
||||
{
|
||||
gl_RenderState.SetColor(blend[0], blend[1], blend[2], blend[3]);
|
||||
gl_FillScreen();
|
||||
}
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.EnableTexture(true);
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Vertex buffer for 2D drawer
|
||||
|
@ -690,6 +823,11 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
|
|||
gl_RenderState.mTextureMatrix.translate(0.f, 1.f, 0.0f);
|
||||
gl_RenderState.EnableTextureMatrix(true);
|
||||
}
|
||||
if (cmd.mTexture->UseType == ETextureType::SWCanvas)
|
||||
{
|
||||
//gl_RenderState.SetTextureMode(swtruecolor ? 0 : 1);
|
||||
//gl_RenderState.SetEffect(EFF_SWQUAD);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -717,6 +855,7 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
|
|||
break;
|
||||
|
||||
}
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
gl_RenderState.EnableTextureMatrix(false);
|
||||
}
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
|
|
@ -45,6 +45,7 @@ class FHardwareTexture;
|
|||
class FShadowMapShader;
|
||||
class FCustomPostProcessShaders;
|
||||
class GLSceneDrawer;
|
||||
class SWSceneDrawer;
|
||||
|
||||
inline float DEG2RAD(float deg)
|
||||
{
|
||||
|
@ -146,6 +147,7 @@ public:
|
|||
FFlatVertexBuffer *mVBO;
|
||||
FSkyVertexBuffer *mSkyVBO;
|
||||
FLightBuffer *mLights;
|
||||
SWSceneDrawer *swdrawer = nullptr;
|
||||
|
||||
GL_IRECT mScreenViewport;
|
||||
GL_IRECT mSceneViewport;
|
||||
|
@ -191,6 +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);
|
||||
|
||||
|
||||
bool StartOffscreen();
|
||||
|
|
|
@ -59,6 +59,7 @@ enum EEffect
|
|||
EFF_SPHEREMAP,
|
||||
EFF_BURN,
|
||||
EFF_STENCIL,
|
||||
EFF_SWQUAD,
|
||||
|
||||
MAX_EFFECTS
|
||||
};
|
||||
|
|
|
@ -79,7 +79,6 @@ CVAR(Bool, gl_sort_textures, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
|
||||
EXTERN_CVAR (Bool, cl_capfps)
|
||||
EXTERN_CVAR (Bool, r_deathcamera)
|
||||
EXTERN_CVAR (Float, underwater_fade_scalar)
|
||||
EXTERN_CVAR (Float, r_visibility)
|
||||
EXTERN_CVAR (Bool, gl_legacy_mode)
|
||||
EXTERN_CVAR (Bool, r_drawvoxels)
|
||||
|
@ -515,138 +514,6 @@ void GLSceneDrawer::DrawScene(int drawmode)
|
|||
RenderTranslucent();
|
||||
}
|
||||
|
||||
|
||||
void gl_FillScreen()
|
||||
{
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
// The fullscreen quad is stored at index 4 in the main vertex buffer.
|
||||
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Draws a blend over the entire view
|
||||
//
|
||||
//==========================================================================
|
||||
void GLSceneDrawer::DrawBlend(sector_t * viewsector)
|
||||
{
|
||||
float blend[4]={0,0,0,0};
|
||||
PalEntry blendv=0;
|
||||
float extra_red;
|
||||
float extra_green;
|
||||
float extra_blue;
|
||||
player_t *player = NULL;
|
||||
|
||||
if (players[consoleplayer].camera != NULL)
|
||||
{
|
||||
player=players[consoleplayer].camera->player;
|
||||
}
|
||||
|
||||
// don't draw sector based blends when an invulnerability colormap is active
|
||||
if (!FixedColormap)
|
||||
{
|
||||
if (!viewsector->e->XFloor.ffloors.Size())
|
||||
{
|
||||
if (viewsector->heightsec && !(viewsector->MoreFlags&SECF_IGNOREHEIGHTSEC))
|
||||
{
|
||||
switch (in_area)
|
||||
{
|
||||
default:
|
||||
case area_normal: blendv = viewsector->heightsec->midmap; break;
|
||||
case area_above: blendv = viewsector->heightsec->topmap; break;
|
||||
case area_below: blendv = viewsector->heightsec->bottommap; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TArray<lightlist_t> & lightlist = viewsector->e->XFloor.lightlist;
|
||||
|
||||
for (unsigned int i = 0; i < lightlist.Size(); i++)
|
||||
{
|
||||
double lightbottom;
|
||||
if (i < lightlist.Size() - 1)
|
||||
lightbottom = lightlist[i + 1].plane.ZatPoint(r_viewpoint.Pos);
|
||||
else
|
||||
lightbottom = viewsector->floorplane.ZatPoint(r_viewpoint.Pos);
|
||||
|
||||
if (lightbottom < r_viewpoint.Pos.Z && (!lightlist[i].caster || !(lightlist[i].caster->flags&FF_FADEWALLS)))
|
||||
{
|
||||
// 3d floor 'fog' is rendered as a blending value
|
||||
blendv = lightlist[i].blend;
|
||||
// If this is the same as the sector's it doesn't apply!
|
||||
if (blendv == viewsector->Colormap.FadeColor) blendv = 0;
|
||||
// a little hack to make this work for Legacy maps.
|
||||
if (blendv.a == 0 && blendv != 0) blendv.a = 128;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (blendv.a == 0)
|
||||
{
|
||||
blendv = R_BlendForColormap(blendv);
|
||||
}
|
||||
|
||||
if (blendv.a == 255)
|
||||
{
|
||||
|
||||
extra_red = blendv.r / 255.0f;
|
||||
extra_green = blendv.g / 255.0f;
|
||||
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();
|
||||
}
|
||||
}
|
||||
else if (blendv.a)
|
||||
{
|
||||
// [Nash] allow user to set blend intensity
|
||||
int cnt = blendv.a;
|
||||
cnt = (int)(cnt * underwater_fade_scalar);
|
||||
|
||||
V_AddBlend(blendv.r / 255.f, blendv.g / 255.f, blendv.b / 255.f, cnt / 255.0f, blend);
|
||||
}
|
||||
}
|
||||
|
||||
// This mostly duplicates the code in shared_sbar.cpp
|
||||
// When I was writing this the original was called too late so that I
|
||||
// couldn't get the blend in time. However, since then I made some changes
|
||||
// here that would get lost if I switched back so I won't do it.
|
||||
|
||||
if (player)
|
||||
{
|
||||
V_AddPlayerBlend(player, blend, 0.5, 175);
|
||||
}
|
||||
|
||||
if (players[consoleplayer].camera != NULL)
|
||||
{
|
||||
// except for fadeto effects
|
||||
player_t *player = (players[consoleplayer].camera->player != NULL) ? players[consoleplayer].camera->player : &players[consoleplayer];
|
||||
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)
|
||||
{
|
||||
gl_RenderState.SetColor(blend[0], blend[1], blend[2], blend[3]);
|
||||
gl_FillScreen();
|
||||
}
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.EnableTexture(true);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Draws player sprites and color blend
|
||||
|
@ -786,6 +653,17 @@ void GLSceneDrawer::SetFixedColormap (player_t *player)
|
|||
gl_RenderState.SetFixedColormap(FixedColormap);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GLSceneDrawer::DrawBlend(sector_t *viewsector)
|
||||
{
|
||||
GLRenderer->DrawBlend(viewsector, !!FixedColormap, true);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Renders one viewpoint in a scene
|
||||
|
|
127
src/gl/scene/gl_swscene.cpp
Normal file
127
src/gl/scene/gl_swscene.cpp
Normal file
|
@ -0,0 +1,127 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2004-2018 Christoph Oelckers
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
/*
|
||||
** gl_swscene.cpp
|
||||
** common overlay code for software and hardware renderer
|
||||
**
|
||||
*/
|
||||
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/system/gl_debug.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "v_palette.h"
|
||||
#include "v_video.h"
|
||||
#include "gl_swscene.h"
|
||||
#include "w_wad.h"
|
||||
#include "d_player.h"
|
||||
#include "textures/bitmap.h"
|
||||
#include "swrenderer/scene/r_light.h"
|
||||
|
||||
// [RH] Base blending values (for e.g. underwater)
|
||||
int BaseBlendR, BaseBlendG, BaseBlendB;
|
||||
float BaseBlendA;
|
||||
|
||||
EXTERN_CVAR(Bool, swtruecolor)
|
||||
|
||||
|
||||
// using FDummyTexture as base because that implements the required software renderer functions.
|
||||
|
||||
class FSWPaletteTexture : public FDummyTexture
|
||||
{
|
||||
public:
|
||||
FSWPaletteTexture()
|
||||
{
|
||||
Width = 256;
|
||||
Height = 1;
|
||||
UseType = ETextureType::MiscPatch;
|
||||
}
|
||||
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf)
|
||||
{
|
||||
memcpy(bmp->GetPixels(), GPalette.BaseColors, 1024);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
class FSWSceneTexture : public FDummyTexture
|
||||
{
|
||||
public:
|
||||
FHardwareTexture *hwtex;
|
||||
|
||||
FSWSceneTexture(int w, int h, int bits)
|
||||
{
|
||||
Width = w;
|
||||
Height = h;
|
||||
WidthBits = bits;
|
||||
UseType = ETextureType::SWCanvas;
|
||||
|
||||
hwtex = new FHardwareTexture(true);
|
||||
new FGLTexture(this, hwtex);
|
||||
}
|
||||
|
||||
// This is just a wrapper around the hardware texture and should never call the bitmap getters - if it does, something is wrong.
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SWSceneDrawer :: CreateResources
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
SWSceneDrawer::SWSceneDrawer()
|
||||
{
|
||||
PaletteTexture = new FSWPaletteTexture;
|
||||
}
|
||||
|
||||
SWSceneDrawer::~SWSceneDrawer()
|
||||
{
|
||||
if (PaletteTexture != nullptr) delete PaletteTexture;
|
||||
if (FBTexture != nullptr) delete FBTexture;
|
||||
}
|
||||
|
||||
void SWSceneDrawer::RenderView(player_t *player)
|
||||
{
|
||||
DCanvas buffer(screen->GetWidth(), screen->GetHeight(), swtruecolor);
|
||||
if (FBTexture == nullptr || FBTexture->hwtex == nullptr || FBTexture->GetWidth() != screen->GetWidth() || FBTexture->GetHeight() != screen->GetHeight() || (swtruecolor?4:1) != FBTexture->WidthBits)
|
||||
{
|
||||
// This manually constructs its own material here.
|
||||
if (FBTexture != nullptr) delete FBTexture;
|
||||
FBTexture = new FSWSceneTexture(screen->GetWidth(), screen->GetHeight(), swtruecolor);
|
||||
FBTexture->hwtex->AllocateBuffer(screen->GetWidth(), screen->GetHeight(), swtruecolor ? 4 : 1);
|
||||
auto mat = FMaterial::ValidateTexture(FBTexture, false);
|
||||
mat->AddTextureLayer(PaletteTexture);
|
||||
}
|
||||
auto buf = FBTexture->hwtex->MapBuffer();
|
||||
if (!buf) I_FatalError("Unable to map buffer for software rendering");
|
||||
buffer.SetBuffer(screen->GetWidth(), screen->GetHeight(), screen->GetWidth() * (swtruecolor ? 4 : 1), buf);
|
||||
SWRenderer->RenderView(player, &buffer);
|
||||
FBTexture->hwtex->CreateTexture(nullptr, screen->GetWidth(), screen->GetHeight(), 0, false, 0, "swbuffer");
|
||||
|
||||
auto map = swrenderer::CameraLight::Instance()->ShaderColormap();
|
||||
screen->Begin2D(false);
|
||||
screen->DrawTexture(FBTexture, 0, 0, DTA_SpecialColormap, map, TAG_DONE);
|
||||
SWRenderer->DrawRemainingPlayerSprites();
|
||||
GLRenderer->DrawBlend(r_viewpoint.sector, !!map, swtruecolor);
|
||||
}
|
|
@ -616,6 +616,7 @@ static const FEffectShader effectshaders[]=
|
|||
{ "spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "shaders/glsl/material_normal.fp", "#define SPHEREMAP\n#define NO_ALPHATEST\n" },
|
||||
{ "burn", "shaders/glsl/main.vp", "shaders/glsl/burn.fp", nullptr, nullptr, "#define SIMPLE\n#define NO_ALPHATEST\n" },
|
||||
{ "stencil", "shaders/glsl/main.vp", "shaders/glsl/stencil.fp", nullptr, nullptr, "#define SIMPLE\n#define NO_ALPHATEST\n" },
|
||||
{ "swrquad", "shaders/glsl/main.vp", "shaders/glsl/swshader.fp", nullptr, nullptr, "#define SIMPLE\n" },
|
||||
};
|
||||
|
||||
FShaderManager::FShaderManager()
|
||||
|
|
|
@ -201,6 +201,7 @@ void OpenGLFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint
|
|||
{
|
||||
if (currentrenderer == 0)
|
||||
Super::RenderTextureView(tex, Viewpoint, FOV);
|
||||
|
||||
else if (GLRenderer != nullptr)
|
||||
{
|
||||
GLRenderer->RenderTextureView(tex, Viewpoint, FOV);
|
||||
|
@ -216,6 +217,9 @@ void OpenGLFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint
|
|||
|
||||
void OpenGLFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int width, int height)
|
||||
{
|
||||
if (currentrenderer == 0)
|
||||
Super::WriteSavePic(player, file, width, height);
|
||||
|
||||
if (GLRenderer != nullptr)
|
||||
GLRenderer->WriteSavePic(player, file, width, height);
|
||||
}
|
||||
|
|
|
@ -177,11 +177,15 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int
|
|||
FGLDebug::LabelObject(GL_TEXTURE, glTex->glTexID, name);
|
||||
lastbound[texunit] = glTex->glTexID;
|
||||
|
||||
if (!buffer)
|
||||
rw = GetTexDimension(w);
|
||||
rh = GetTexDimension(h);
|
||||
if (glBufferID > 0)
|
||||
{
|
||||
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||
buffer = nullptr;
|
||||
}
|
||||
else if (!buffer)
|
||||
{
|
||||
rw = GetTexDimension (w);
|
||||
rh = GetTexDimension (h);
|
||||
|
||||
// The texture must at least be initialized if no data is present.
|
||||
glTex->mipmapped = false;
|
||||
buffer=(unsigned char *)calloc(4,rw * (rh+1));
|
||||
|
@ -190,9 +194,6 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int
|
|||
}
|
||||
else
|
||||
{
|
||||
rw = GetTexDimension (w);
|
||||
rh = GetTexDimension (h);
|
||||
|
||||
if (rw < w || rh < h)
|
||||
{
|
||||
// The texture is larger than what the hardware can handle so scale it down.
|
||||
|
@ -208,9 +209,42 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int
|
|||
// store the physical size.
|
||||
texwidth = rw;
|
||||
texheight = rh;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, texformat, rw, rh, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
|
||||
|
||||
if (deletebuffer) free(buffer);
|
||||
int sourcetype;
|
||||
if (glTextureBytes > 0)
|
||||
{
|
||||
if (glTextureBytes < 4) glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
if (gl.legacyMode)
|
||||
{
|
||||
// Do not use 2 and 3 here. They won't do anything useful!!!
|
||||
static const int ITypes[] = { GL_LUMINANCE8, GL_LUMINANCE8_ALPHA8, GL_RGB8, GL_RGBA8 };
|
||||
static const int STypes[] = { GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGR, GL_BGRA };
|
||||
|
||||
texformat = ITypes[glTextureBytes - 1];
|
||||
sourcetype = STypes[glTextureBytes - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
static const int ITypes[] = { GL_R8, GL_RG8, GL_RGB8, GL_RGBA8 };
|
||||
static const int STypes[] = { GL_RED, GL_RG, GL_BGR, GL_BGRA };
|
||||
|
||||
texformat = ITypes[glTextureBytes - 1];
|
||||
sourcetype = STypes[glTextureBytes - 1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sourcetype = GL_BGRA;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, texformat, rw, rh, 0, sourcetype, GL_UNSIGNED_BYTE, buffer);
|
||||
|
||||
if (deletebuffer && buffer) free(buffer);
|
||||
else if (glBufferID)
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
}
|
||||
|
||||
if (mipmap && TexFilter[gl_texture_filter].mipmapping)
|
||||
{
|
||||
|
@ -223,6 +257,33 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int
|
|||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
void FHardwareTexture::AllocateBuffer(int w, int h, int texelsize)
|
||||
{
|
||||
int rw = GetTexDimension(w);
|
||||
int rh = GetTexDimension(h);
|
||||
if (texelsize < 1 || texelsize > 4) texelsize = 4;
|
||||
glTextureBytes = texelsize;
|
||||
if (rw == w || rh == h)
|
||||
{
|
||||
glGenBuffers(1, &glBufferID);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, glBufferID);
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, w*h*texelsize, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t *FHardwareTexture::MapBuffer()
|
||||
{
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, glBufferID);
|
||||
return (uint8_t*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Creates a texture
|
||||
|
@ -313,6 +374,7 @@ void FHardwareTexture::CleanUnused(SpriteHits &usedtranslations)
|
|||
FHardwareTexture::~FHardwareTexture()
|
||||
{
|
||||
Clean(true);
|
||||
glDeleteBuffers(1, &glBufferID);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -66,6 +66,8 @@ private:
|
|||
TranslatedTexture glDefTex;
|
||||
TArray<TranslatedTexture> glTex_Translated;
|
||||
unsigned int glDepthID; // only used by camera textures
|
||||
unsigned int glBufferID = 0;
|
||||
int glTextureBytes = 4;
|
||||
|
||||
TranslatedTexture * GetTexID(int translation);
|
||||
|
||||
|
@ -82,6 +84,9 @@ public:
|
|||
void BindToFrameBuffer();
|
||||
|
||||
unsigned int Bind(int texunit, int translation, bool needmipmap);
|
||||
void AllocateBuffer(int w, int h, int texelsize);
|
||||
uint8_t *MapBuffer();
|
||||
|
||||
unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const FString &name);
|
||||
unsigned int GetTextureHandle(int translation);
|
||||
|
||||
|
|
|
@ -73,6 +73,22 @@ FGLTexture::FGLTexture(FTexture * tx, bool expandpatches)
|
|||
tex->gl_info.SystemTexture[expandpatches] = this;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Constructor 2 for the SW framebuffer which provides its own hardware texture.
|
||||
//
|
||||
//===========================================================================
|
||||
FGLTexture::FGLTexture(FTexture * tx, FHardwareTexture *hwtex)
|
||||
{
|
||||
assert(tx->gl_info.SystemTexture[0] == NULL);
|
||||
tex = tx;
|
||||
|
||||
mHwTexture = hwtex;
|
||||
lastSampler = 254;
|
||||
lastTranslation = -1;
|
||||
tex->gl_info.SystemTexture[0] = this;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Destructor
|
||||
|
@ -82,6 +98,7 @@ FGLTexture::FGLTexture(FTexture * tx, bool expandpatches)
|
|||
FGLTexture::~FGLTexture()
|
||||
{
|
||||
Clean(true);
|
||||
for (auto & i : tex->gl_info.SystemTexture) if (i == this) i = nullptr;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -174,7 +191,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla
|
|||
int w=0, h=0;
|
||||
|
||||
// Create this texture
|
||||
unsigned char * buffer = NULL;
|
||||
unsigned char * buffer = nullptr;
|
||||
|
||||
if (!tex->bHasCanvas)
|
||||
{
|
||||
|
|
|
@ -45,7 +45,7 @@ struct FTexCoordInfo
|
|||
|
||||
//===========================================================================
|
||||
//
|
||||
// this is the texture maintenance class for OpenGL.
|
||||
// device independent wrapper around the hardware texture and its sampler state
|
||||
//
|
||||
//===========================================================================
|
||||
class FMaterial;
|
||||
|
@ -68,10 +68,12 @@ private:
|
|||
|
||||
public:
|
||||
FGLTexture(FTexture * tx, bool expandpatches);
|
||||
FGLTexture(FTexture * tx, FHardwareTexture *hwtex); // for the SW framebuffer
|
||||
~FGLTexture();
|
||||
|
||||
void Clean(bool all);
|
||||
void CleanUnused(SpriteHits &usedtranslations);
|
||||
bool isInitialized() const { return mHwTexture != nullptr; }
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
|
@ -124,6 +126,12 @@ public:
|
|||
void SetSpriteRect();
|
||||
void Precache();
|
||||
void PrecacheList(SpriteHits &translations);
|
||||
void AddTextureLayer(FTexture *tex)
|
||||
{
|
||||
FTextureLayer layer = { tex, false };
|
||||
ValidateTexture(tex, false);
|
||||
mTextureLayers.Push(layer);
|
||||
}
|
||||
bool isMasked() const
|
||||
{
|
||||
return !!mBaseLayer->tex->bMasked;
|
||||
|
|
|
@ -54,26 +54,21 @@ PolyRenderer::PolyRenderer()
|
|||
{
|
||||
}
|
||||
|
||||
void PolyRenderer::RenderView(player_t *player)
|
||||
void PolyRenderer::RenderView(player_t *player, DCanvas *target)
|
||||
{
|
||||
using namespace swrenderer;
|
||||
|
||||
if (screen->LockCanvas())
|
||||
{
|
||||
RenderTarget = screen->GetCanvas();
|
||||
RenderTarget = target;
|
||||
int width = SCREENWIDTH;
|
||||
int height = SCREENHEIGHT;
|
||||
float trueratio;
|
||||
ActiveRatio(width, height, &trueratio);
|
||||
//viewport->SetViewport(&Thread, width, height, trueratio);
|
||||
|
||||
int width = SCREENWIDTH;
|
||||
int height = SCREENHEIGHT;
|
||||
float trueratio;
|
||||
ActiveRatio(width, height, &trueratio);
|
||||
//viewport->SetViewport(&Thread, width, height, trueratio);
|
||||
RenderActorView(player->mo, false);
|
||||
|
||||
RenderActorView(player->mo, false);
|
||||
|
||||
Threads.MainThread()->FlushDrawQueue();
|
||||
DrawerThreads::WaitForWorkers();
|
||||
screen->UnlockCanvas();
|
||||
}
|
||||
Threads.MainThread()->FlushDrawQueue();
|
||||
DrawerThreads::WaitForWorkers();
|
||||
}
|
||||
|
||||
void PolyRenderer::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines)
|
||||
|
|
|
@ -45,7 +45,7 @@ class PolyRenderer
|
|||
public:
|
||||
PolyRenderer();
|
||||
|
||||
void RenderView(player_t *player);
|
||||
void RenderView(player_t *player, DCanvas *target);
|
||||
void RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines);
|
||||
void RenderRemainingPlayerSprites();
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ class player_t;
|
|||
struct sector_t;
|
||||
class FCanvasTexture;
|
||||
class FileWriter;
|
||||
class DCanvas;
|
||||
|
||||
struct FRenderer
|
||||
{
|
||||
|
@ -22,7 +23,7 @@ struct FRenderer
|
|||
virtual void Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist) = 0;
|
||||
|
||||
// render 3D view
|
||||
virtual void RenderView(player_t *player) = 0;
|
||||
virtual void RenderView(player_t *player, DCanvas *target) = 0;
|
||||
|
||||
// renders view to a savegame picture
|
||||
virtual void WriteSavePic(player_t *player, FileWriter *file, int width, int height) = 0;
|
||||
|
|
|
@ -175,13 +175,13 @@ void FSoftwareRenderer::Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &
|
|||
}
|
||||
}
|
||||
|
||||
void FSoftwareRenderer::RenderView(player_t *player)
|
||||
void FSoftwareRenderer::RenderView(player_t *player, DCanvas *target)
|
||||
{
|
||||
if (r_polyrenderer)
|
||||
{
|
||||
PolyRenderer::Instance()->Viewpoint = r_viewpoint;
|
||||
PolyRenderer::Instance()->Viewwindow = r_viewwindow;
|
||||
PolyRenderer::Instance()->RenderView(player);
|
||||
PolyRenderer::Instance()->RenderView(player, target);
|
||||
r_viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||
r_viewwindow = PolyRenderer::Instance()->Viewwindow;
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ void FSoftwareRenderer::RenderView(player_t *player)
|
|||
{
|
||||
mScene.MainThread()->Viewport->viewpoint = r_viewpoint;
|
||||
mScene.MainThread()->Viewport->viewwindow = r_viewwindow;
|
||||
mScene.RenderView(player);
|
||||
mScene.RenderView(player, target);
|
||||
r_viewpoint = mScene.MainThread()->Viewport->viewpoint;
|
||||
r_viewwindow = mScene.MainThread()->Viewport->viewwindow;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ struct FSoftwareRenderer : public FRenderer
|
|||
void Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist) override;
|
||||
|
||||
// render 3D view
|
||||
void RenderView(player_t *player) override;
|
||||
void RenderView(player_t *player, DCanvas *target) override;
|
||||
|
||||
// renders view to a savegame picture
|
||||
void WriteSavePic (player_t *player, FileWriter *file, int width, int height) override;
|
||||
|
|
|
@ -64,6 +64,7 @@ void PeekThreadedErrorPane();
|
|||
#endif
|
||||
|
||||
EXTERN_CVAR(Int, r_clearbuffer)
|
||||
EXTERN_CVAR(Bool, swtruecolor)
|
||||
|
||||
CVAR(Bool, r_scene_multithreaded, false, 0);
|
||||
CVAR(Bool, r_models, false, 0);
|
||||
|
@ -87,44 +88,38 @@ namespace swrenderer
|
|||
clearcolor = color;
|
||||
}
|
||||
|
||||
void RenderScene::RenderView(player_t *player)
|
||||
void RenderScene::RenderView(player_t *player, DCanvas *target)
|
||||
{
|
||||
if (screen->LockCanvas())
|
||||
auto viewport = MainThread()->Viewport.get();
|
||||
viewport->RenderTarget = target;
|
||||
|
||||
int width = SCREENWIDTH;
|
||||
int height = SCREENHEIGHT;
|
||||
float trueratio;
|
||||
ActiveRatio(width, height, &trueratio);
|
||||
viewport->SetViewport(MainThread(), width, height, trueratio);
|
||||
|
||||
if (r_clearbuffer != 0)
|
||||
{
|
||||
auto viewport = MainThread()->Viewport.get();
|
||||
viewport->RenderTarget = screen->GetCanvas();
|
||||
|
||||
int width = SCREENWIDTH;
|
||||
int height = SCREENHEIGHT;
|
||||
float trueratio;
|
||||
ActiveRatio(width, height, &trueratio);
|
||||
viewport->SetViewport(MainThread(), width, height, trueratio);
|
||||
|
||||
if (r_clearbuffer != 0)
|
||||
if (!viewport->RenderTarget->IsBgra())
|
||||
{
|
||||
if (!viewport->RenderTarget->IsBgra())
|
||||
{
|
||||
memset(viewport->RenderTarget->GetPixels(), clearcolor, viewport->RenderTarget->GetPitch() * viewport->RenderTarget->GetHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t bgracolor = GPalette.BaseColors[clearcolor].d;
|
||||
int size = viewport->RenderTarget->GetPitch() * viewport->RenderTarget->GetHeight();
|
||||
uint32_t *dest = (uint32_t *)viewport->RenderTarget->GetPixels();
|
||||
for (int i = 0; i < size; i++)
|
||||
dest[i] = bgracolor;
|
||||
}
|
||||
memset(viewport->RenderTarget->GetPixels(), clearcolor, viewport->RenderTarget->GetPitch() * viewport->RenderTarget->GetHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t bgracolor = GPalette.BaseColors[clearcolor].d;
|
||||
int size = viewport->RenderTarget->GetPitch() * viewport->RenderTarget->GetHeight();
|
||||
uint32_t *dest = (uint32_t *)viewport->RenderTarget->GetPixels();
|
||||
for (int i = 0; i < size; i++)
|
||||
dest[i] = bgracolor;
|
||||
}
|
||||
|
||||
RenderActorView(player->mo);
|
||||
|
||||
DrawerWaitCycles.Clock();
|
||||
DrawerThreads::WaitForWorkers();
|
||||
DrawerWaitCycles.Unclock();
|
||||
|
||||
screen->UnlockCanvas();
|
||||
}
|
||||
|
||||
RenderActorView(player->mo);
|
||||
|
||||
DrawerWaitCycles.Clock();
|
||||
DrawerThreads::WaitForWorkers();
|
||||
DrawerWaitCycles.Unclock();
|
||||
}
|
||||
|
||||
void RenderScene::RenderActorView(AActor *actor, bool dontmaplines)
|
||||
|
@ -367,15 +362,18 @@ namespace swrenderer
|
|||
viewactive = savedviewactive;
|
||||
}
|
||||
|
||||
|
||||
void RenderScene::ScreenResized()
|
||||
{
|
||||
auto viewport = MainThread()->Viewport.get();
|
||||
viewport->RenderTarget = screen->GetCanvas();
|
||||
int width = SCREENWIDTH;
|
||||
int height = SCREENHEIGHT;
|
||||
viewport->RenderTarget = new DCanvas(width, height, swtruecolor); // Some code deeper down needs something valid here, so give it a dummy canvas.
|
||||
float trueratio;
|
||||
ActiveRatio(width, height, &trueratio);
|
||||
viewport->SetViewport(MainThread(), SCREENWIDTH, SCREENHEIGHT, trueratio);
|
||||
delete viewport->RenderTarget;
|
||||
viewport->RenderTarget = nullptr;
|
||||
}
|
||||
|
||||
void RenderScene::Deinit()
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace swrenderer
|
|||
|
||||
void SetClearColor(int color);
|
||||
|
||||
void RenderView(player_t *player);
|
||||
void RenderView(player_t *player, DCanvas *target);
|
||||
void RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines = false);
|
||||
|
||||
bool DontMapLines() const { return dontmaplines; }
|
||||
|
|
|
@ -307,7 +307,6 @@ void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms)
|
|||
AddCommand(&dg);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
@ -34,7 +34,6 @@ public:
|
|||
{
|
||||
DTF_Wrap = 1,
|
||||
DTF_Scissor = 2,
|
||||
//DTF_SpecialColormap = 4,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -965,6 +965,12 @@ void DFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, dou
|
|||
SWRenderer->RenderTextureView(tex, Viewpoint, FOV);
|
||||
}
|
||||
|
||||
void DFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int width, int height)
|
||||
{
|
||||
SWRenderer->WriteSavePic(player, file, width, height);
|
||||
}
|
||||
|
||||
|
||||
CCMD(clean)
|
||||
{
|
||||
Printf ("CleanXfac: %d\nCleanYfac: %d\n", CleanXfac, CleanYfac);
|
||||
|
|
|
@ -226,18 +226,12 @@ public:
|
|||
|
||||
bool SetBuffer(int width, int height, int pitch, uint8_t *buffer)
|
||||
{
|
||||
if (PixelBuffer == nullptr)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
Pitch = pitch;
|
||||
PixelBuffer = buffer;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
assert(buffer);
|
||||
Width = width;
|
||||
Height = height;
|
||||
Pitch = pitch;
|
||||
PixelBuffer = buffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -339,10 +333,6 @@ public:
|
|||
|
||||
virtual bool LegacyHardware() const { return false; } // only for reporting SM1.4 support to the stat collector
|
||||
|
||||
// For FrameBuffers with a software canvas that requires special preparation before being used.
|
||||
virtual bool LockCanvas() { return true; }
|
||||
virtual void UnlockCanvas() {}
|
||||
|
||||
// Begin 2D drawing operations.
|
||||
// Returns true if hardware-accelerated 2D has been entered, false if not.
|
||||
virtual bool Begin2D(bool copy3d);
|
||||
|
@ -359,7 +349,7 @@ public:
|
|||
virtual void SetClearColor(int color) {}
|
||||
virtual uint32_t GetCaps();
|
||||
virtual void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV);
|
||||
virtual void WriteSavePic(player_t *player, FileWriter *file, int width, int height) {}
|
||||
virtual void WriteSavePic(player_t *player, FileWriter *file, int width, int height);
|
||||
virtual void RenderView(player_t *player) {}
|
||||
|
||||
// Screen wiping
|
||||
|
|
31
wadsrc/static/shaders/glsl/swshader.fp
Normal file
31
wadsrc/static/shaders/glsl/swshader.fp
Normal file
|
@ -0,0 +1,31 @@
|
|||
in vec4 vTexCoord;
|
||||
out vec4 FragColor;
|
||||
|
||||
vec4 TextureLookup(vec2 tex_coord)
|
||||
{
|
||||
if (uTextureMode == 1)
|
||||
{
|
||||
float index = texture(tex, tex_coord).x;
|
||||
index = index * 256.0 + 0.5; // We only have 256 color palettes here.
|
||||
return texture(texture2, vec2(index, 0.5));
|
||||
}
|
||||
else
|
||||
{
|
||||
return texture(tex, tex_coord);
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
if (uFixedColormap == 0)
|
||||
{
|
||||
FragColor = TextureLookup(vTexCoord.xy);
|
||||
}
|
||||
else
|
||||
{
|
||||
vec4 frag = TextureLookup(vTexCoord.xy);
|
||||
float gray = dot(frag.rgb, vec3(0.4, 0.56, 0.14));
|
||||
vec4 cm = uFixedColormapStart + gray * uFixedColormapRange;
|
||||
FragColor = vec4(clamp(cm.rgb, 0.0, 1.0), 1.0);
|
||||
}
|
||||
}
|
32
wadsrc/static/shaders/swgl/swshadergl2.fp
Normal file
32
wadsrc/static/shaders/swgl/swshadergl2.fp
Normal file
|
@ -0,0 +1,32 @@
|
|||
uniform sampler2D tex;
|
||||
uniform sampler2D pal;
|
||||
uniform vec4 uColor1;
|
||||
uniform vec4 uColor2;
|
||||
|
||||
vec4 TextureLookup(vec2 tex_coord)
|
||||
{
|
||||
#ifdef PAL_TEX
|
||||
float index = texture2D(tex, tex_coord).x;
|
||||
index = index * 256.0 + 0.5; // We only have full 256-color palettes here.
|
||||
return texture2D(pal, vec2(index, 0.5));
|
||||
#else
|
||||
return texture2D(tex, tex_coord);
|
||||
#endif
|
||||
}
|
||||
|
||||
float grayscale(vec4 rgb)
|
||||
{
|
||||
return dot(color.rgb, vec3(0.4, 0.56, 0.14));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifndef SPECIALCM
|
||||
FragColor = TextureLookup(gl_TexCoord[0].xy);
|
||||
#else
|
||||
vec4 frag = TextureLookup(gl_TexCoord[0].xy);
|
||||
float gray = grayscale(frag);
|
||||
vec4 cm = uColor1 + gray * uColor2;
|
||||
gl_FragColor = vec4(clamp(cm.rgb, 0.0, 1.0), 1.0);
|
||||
#endif
|
||||
}
|
6
wadsrc/static/shaders/swgl/swshadergl2.vp
Normal file
6
wadsrc/static/shaders/swgl/swshadergl2.vp
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
void main()
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_Position = ftransform();
|
||||
}
|
Loading…
Reference in a new issue