- removed the remaining calls from the FRenderer interface from the main game code.

This does not work with a setup where the same backend is driving both renderers.
Most of this is now routed through 'screen', and the decision between renderers has to be made inside the actual render functions.
The software renderer is still driven by a thin opaque interface to keep it mostly an isolated module.
This commit is contained in:
Christoph Oelckers 2018-04-04 00:21:25 +02:00
parent 927b351174
commit d474b849a5
18 changed files with 243 additions and 238 deletions

View file

@ -805,7 +805,7 @@ void D_Display ()
// [ZZ] execute event hook that we just started the frame
//E_RenderFrame();
//
Renderer->RenderView(&players[consoleplayer]);
screen->RenderView(&players[consoleplayer]);
screen->Begin2D(viewactive);
// todo: These need to go into RenderView.
@ -2275,38 +2275,6 @@ static void CheckCmdLine()
}
}
//==========================================================================
//
//
//
//==========================================================================
extern int currentrenderer;
EXTERN_CVAR(Int, vid_renderer)
FRenderer *gl_CreateInterface();
FRenderer *CreateSWRenderer();
static void DeleteRenderer()
{
if (Renderer != NULL) delete Renderer;
if (SWRenderer != NULL) delete SWRenderer;
}
void D_CreateRenderer()
{
currentrenderer = vid_renderer;
if (currentrenderer == 1)
Printf("Renderer: OpenGL\n");
else
Printf("Renderer: Software on OpenGL\n");
if (Renderer == NULL)
{
Renderer = gl_CreateInterface();
SWRenderer = CreateSWRenderer();
atterm(DeleteRenderer);
}
}
//==========================================================================
//
@ -2492,7 +2460,6 @@ void D_DoomMain (void)
{
if (!batchrun) Printf ("I_Init: Setting up machine state.\n");
I_Init ();
D_CreateRenderer();
}
if (!batchrun) Printf ("V_Init: allocate screen.\n");

View file

@ -2247,7 +2247,7 @@ static void PutSavePic (FileWriter *file, int width, int height)
}
else
{
Renderer->WriteSavePic(&players[consoleplayer], file, width, height);
screen->WriteSavePic(&players[consoleplayer], file, width, height);
}
}

View file

@ -35,6 +35,10 @@
#include "w_wad.h"
#include "vectors.h"
#include "doomstat.h"
#include "i_time.h"
#include "p_effect.h"
#include "d_player.h"
#include "a_dynlight.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"
@ -46,6 +50,7 @@
#include "gl/renderer/gl_renderbuffers.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_scenedrawer.h"
#include "gl/scene/gl_portal.h"
#include "gl/shaders/gl_shader.h"
#include "gl/shaders/gl_ambientshader.h"
@ -69,8 +74,10 @@
#include "r_videoscale.h"
EXTERN_CVAR(Int, screenblocks)
EXTERN_CVAR(Bool, cl_capfps)
CVAR(Bool, gl_scale_viewport, true, CVAR_ARCHIVE);
extern bool NoInterpolateView;
//===========================================================================
//
@ -411,6 +418,122 @@ void FGLRenderer::EndOffscreen()
glBindFramebuffer(GL_FRAMEBUFFER, mOldFBID);
}
//-----------------------------------------------------------------------------
//
// renders the view
//
//-----------------------------------------------------------------------------
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)
{
fovratio = 1.333333f;
}
else
{
fovratio = ratio;
}
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();
}
//===========================================================================
//
// Camera texture rendering
//
//===========================================================================
void FGLRenderer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV)
{
FMaterial * gltex = FMaterial::ValidateTexture(tex, false);
int width = gltex->TextureWidth();
int height = gltex->TextureHeight();
if (gl.legacyMode)
{
// In legacy mode, fail if the requested texture is too large.
if (gltex->GetWidth() > screen->GetWidth() || gltex->GetHeight() > screen->GetHeight()) return;
glFlush();
}
else
{
StartOffscreen();
gltex->BindToFrameBuffer();
}
GL_IRECT bounds;
bounds.left = bounds.top = 0;
bounds.width = FHardwareTexture::GetTexDimension(gltex->GetWidth());
bounds.height = FHardwareTexture::GetTexDimension(gltex->GetHeight());
GLSceneDrawer drawer;
drawer.FixedColormap = CM_DEFAULT;
gl_RenderState.SetFixedColormap(CM_DEFAULT);
drawer.RenderViewpoint(Viewpoint, &bounds, FOV, (float)width / height, (float)width / height, false, false);
if (gl.legacyMode)
{
glFlush();
gl_RenderState.SetMaterial(gltex, 0, 0, -1, false);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bounds.width, bounds.height);
}
else
{
EndOffscreen();
}
tex->SetUpdated();
}
void FGLRenderer::WriteSavePic(player_t *player, FileWriter *file, int width, int height)
{
// Todo: This needs to call the software renderer and process the returned image, if so desired.
// This also needs to take out parts of the scene drawer so they can be shared between renderers.
GLSceneDrawer drawer;
drawer.WriteSavePic(player, file, width, height);
}
//===========================================================================
//
// Vertex buffer for 2D drawer

View file

@ -171,8 +171,6 @@ public:
void FlushTextures();
void SetupLevel();
void RenderView(player_t* player);
void RenderScreenQuad();
void PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D);
void AmbientOccludeScene();
@ -190,6 +188,9 @@ public:
void Flush();
void GetSpecialTextures();
void Draw2D(F2DDrawer *data);
void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV);
void WriteSavePic(player_t *player, FileWriter *file, int width, int height);
void RenderView(player_t *player);
bool StartOffscreen();

View file

@ -84,10 +84,6 @@ EXTERN_CVAR (Float, r_visibility)
EXTERN_CVAR (Bool, gl_legacy_mode)
EXTERN_CVAR (Bool, r_drawvoxels)
extern bool NoInterpolateView;
int camtexcount; // used to decide how VSync is done. It just counts the number of camera textures per frame.
//-----------------------------------------------------------------------------
//
// R_FrustumAngle
@ -889,63 +885,6 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, f
return lviewsector;
}
//-----------------------------------------------------------------------------
//
// renders the view
//
//-----------------------------------------------------------------------------
void FGLRenderer::RenderView (player_t* player)
{
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)
{
fovratio = 1.333333f;
}
else
{
fovratio = ratio;
}
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();
}
//===========================================================================
//
// Render the view to a savegame picture
@ -989,118 +928,3 @@ void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width,
M_CreatePNG (file, scr + ((height-1) * width * 3), NULL, SS_RGB, width, height, -width * 3, Gamma);
M_Free(scr);
}
//===========================================================================
//
//
//
//===========================================================================
struct FGLInterface : public FRenderer
{
void Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist) override;
void RenderView(player_t *player) override;
void WriteSavePic (player_t *player, FileWriter *file, int width, int height) override;
void RenderTextureView (FCanvasTexture *self, AActor *viewpoint, double fov) override;
};
//==========================================================================
//
// DFrameBuffer :: Precache
//
//==========================================================================
void gl_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist);
void FGLInterface::Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist)
{
gl_PrecacheTexture(texhitlist, actorhitlist);
}
//===========================================================================
//
// Render the view to a savegame picture
//
//===========================================================================
void FGLInterface::WriteSavePic (player_t *player, FileWriter *file, int width, int height)
{
GLSceneDrawer drawer;
drawer.WriteSavePic(player, file, width, height);
}
//===========================================================================
//
//
//
//===========================================================================
void FGLInterface::RenderView(player_t *player)
{
GLRenderer->RenderView(player);
}
//===========================================================================
//
// Camera texture rendering
//
//===========================================================================
CVAR(Bool, gl_usefb, false , CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
extern TexFilter_s TexFilter[];
void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, double FOV)
{
FMaterial * gltex = FMaterial::ValidateTexture(tex, false);
int width = gltex->TextureWidth();
int height = gltex->TextureHeight();
if (gl.legacyMode)
{
// In legacy mode, fail if the requested texture is too large.
if (gltex->GetWidth() > screen->GetWidth() || gltex->GetHeight() > screen->GetHeight()) return;
glFlush();
}
else
{
GLRenderer->StartOffscreen();
gltex->BindToFrameBuffer();
}
GL_IRECT bounds;
bounds.left=bounds.top=0;
bounds.width=FHardwareTexture::GetTexDimension(gltex->GetWidth());
bounds.height=FHardwareTexture::GetTexDimension(gltex->GetHeight());
GLSceneDrawer drawer;
drawer.FixedColormap = CM_DEFAULT;
gl_RenderState.SetFixedColormap(CM_DEFAULT);
drawer.RenderViewpoint(Viewpoint, &bounds, FOV, (float)width/height, (float)width/height, false, false);
if (gl.legacyMode)
{
glFlush();
gl_RenderState.SetMaterial(gltex, 0, 0, -1, false);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bounds.width, bounds.height);
}
else
{
GLRenderer->EndOffscreen();
}
tex->SetUpdated();
camtexcount++;
}
//===========================================================================
//
//
//
//===========================================================================
FRenderer *gl_CreateInterface()
{
return new FGLInterface;
}

View file

@ -190,6 +190,50 @@ void OpenGLFrameBuffer::Update()
GLRenderer->SetOutputViewport(nullptr);
}
//===========================================================================
//
//
//
//===========================================================================
extern int currentrenderer;
void OpenGLFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV)
{
if (currentrenderer == 0)
Super::RenderTextureView(tex, Viewpoint, FOV);
else if (GLRenderer != nullptr)
{
GLRenderer->RenderTextureView(tex, Viewpoint, FOV);
camtexcount++;
}
}
//===========================================================================
//
// Render the view to a savegame picture
//
//===========================================================================
void OpenGLFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int width, int height)
{
if (GLRenderer != nullptr)
GLRenderer->WriteSavePic(player, file, width, height);
}
//===========================================================================
//
//
//
//===========================================================================
void OpenGLFrameBuffer::RenderView(player_t *player)
{
if (GLRenderer != nullptr)
GLRenderer->RenderView(player);
}
//===========================================================================
//
//
@ -198,7 +242,6 @@ void OpenGLFrameBuffer::Update()
EXTERN_CVAR(Bool, r_drawvoxels)
EXTERN_CVAR(Int, gl_tonemap)
extern int currentrenderer;
uint32_t OpenGLFrameBuffer::GetCaps()
{
@ -235,7 +278,6 @@ uint32_t OpenGLFrameBuffer::GetCaps()
//==========================================================================
CVAR(Bool, gl_finishbeforeswap, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
extern int camtexcount;
void OpenGLFrameBuffer::Swap()
{

View file

@ -49,6 +49,9 @@ public:
void InitForLevel() override;
void SetClearColor(int color) override;
uint32_t GetCaps() override;
void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV) override;
void WriteSavePic(player_t *player, FileWriter *file, int width, int height) override;
void RenderView(player_t *player) override;
// Retrieves a buffer containing image data for a screenshot.
// Hint: Pitch can be negative for upside-down images, in which case buffer
@ -76,6 +79,7 @@ private:
PalEntry Flash; // Only needed to support some cruft in the interface that only makes sense for the software renderer
PalEntry SourcePalette[256]; // This is where unpaletted textures get their palette from
uint8_t *ScreenshotBuffer; // What the name says. This must be maintained because the software renderer can return a locked canvas surface which the caller cannot release.
int camtexcount = 0;
class Wiper
{

View file

@ -741,10 +741,7 @@ bool AActor::SetState (FState *newstate, bool nofunction)
newstate = newstate->GetNextState();
} while (tics == 0);
if (Renderer != NULL)
{
SetDynamicLights();
}
SetDynamicLights();
return true;
}

View file

@ -3427,6 +3427,8 @@ void P_GetPolySpots (MapData * map, TArray<FNodeBuilder::FPolyStart> &spots, TAr
// Preloads all relevant graphics for the level.
//
//===========================================================================
extern int currentrenderer;
void gl_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist);
static void P_PrecacheLevel()
{
@ -3501,7 +3503,11 @@ static void P_PrecacheLevel()
if (tex.Exists()) hitlist[tex.GetIndex()] |= FTextureManager::HIT_Wall;
}
Renderer->Precache(hitlist, actorhitlist);
// This is just a temporary solution, until the hardware renderer's texture manager is in a better state.
if (currentrenderer == 0)
SWRenderer->Precache(hitlist, actorhitlist);
else
gl_PrecacheTexture(hitlist, actorhitlist);
delete[] hitlist;
}

View file

@ -9,9 +9,6 @@
EXTERN_CVAR (Float, dimamount)
EXTERN_CVAR (Color, dimcolor)
struct FRenderer;
FRenderer *gl_CreateInterface();
class SDLGLVideo : public IVideo
{
public:

View file

@ -4,7 +4,6 @@
#include <stdio.h>
struct FRenderer;
extern FRenderer *Renderer;
extern FRenderer *SWRenderer;
class FSerializer;
@ -17,27 +16,32 @@ class FileWriter;
struct FRenderer
{
virtual ~FRenderer() {}
// precache one texture
virtual void Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist) = 0;
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) = 0;
// renders view to a savegame picture
virtual void WriteSavePic (player_t *player, FileWriter *file, int width, int height) = 0;
virtual void WriteSavePic(player_t *player, FileWriter *file, int width, int height) = 0;
// render to a camera texture
virtual void RenderTextureView(FCanvasTexture *tex, AActor *viewpoint, double fov) = 0;
virtual void RenderTextureView(FCanvasTexture *tex, AActor *viewpoint, double fov) = 0;
// draws player sprites with hardware acceleration (only useful for software rendering)
virtual void DrawRemainingPlayerSprites() {}
virtual void DrawRemainingPlayerSprites() = 0;
// set up the colormap for a newly loaded level.
virtual void SetColormap() {}
virtual void SetColormap() = 0;
virtual void OnModeSet() = 0;
virtual void SetClearColor(int color) = 0;
virtual void Init() = 0;
virtual void OnModeSet () {}
virtual void SetClearColor(int color) {};
};

View file

@ -392,6 +392,17 @@ subsector_t *R_PointInSubsector (fixed_t x, fixed_t y)
return (subsector_t *)((uint8_t *)node - 1);
}
//==========================================================================
//
//
//
//==========================================================================
extern int currentrenderer;
EXTERN_CVAR(Int, vid_renderer)
FRenderer *CreateSWRenderer();
//==========================================================================
//
// R_Init
@ -405,6 +416,19 @@ void R_Init ()
StartScreen->Progress();
R_InitTranslationTables ();
R_SetViewSize (screenblocks);
currentrenderer = vid_renderer;
if (currentrenderer == 1)
Printf("Renderer: OpenGL\n");
else
Printf("Renderer: Software on OpenGL\n");
if (SWRenderer == NULL)
{
SWRenderer = CreateSWRenderer();
}
SWRenderer->Init();
}
//==========================================================================
@ -415,6 +439,8 @@ void R_Init ()
static void R_Shutdown ()
{
if (SWRenderer != nullptr) delete SWRenderer;
SWRenderer = nullptr;
R_DeinitTranslationTables();
R_DeinitColormaps ();
FCanvasTextureInfo::EmptyList();
@ -1079,7 +1105,7 @@ void FCanvasTextureInfo::UpdateAll ()
{
if (probe->Viewpoint != NULL && probe->Texture->bNeedsUpdate)
{
Renderer->RenderTextureView(probe->Texture, probe->Viewpoint, probe->FOV);
screen->RenderTextureView(probe->Texture, probe->Viewpoint, probe->FOV);
}
}
}

View file

@ -52,6 +52,8 @@
#include "p_setup.h"
#include "g_levellocals.h"
extern int currentrenderer;
// [BB] Use ZDoom's freelook limit for the sotfware renderer.
// Note: ZDoom's limit is chosen such that the sky is rendered properly.
CUSTOM_CVAR (Bool, cl_oldfreelooklimit, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
@ -80,6 +82,10 @@ CUSTOM_CVAR(Bool, r_polyrenderer, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOI
using namespace swrenderer;
FSoftwareRenderer::FSoftwareRenderer()
{
}
void FSoftwareRenderer::Init()
{
R_InitShadeMaps();
InitSWColorMaps();
@ -240,7 +246,9 @@ void FSoftwareRenderer::DrawRemainingPlayerSprites()
void FSoftwareRenderer::OnModeSet ()
{
mScene.ScreenResized();
// This does not work if the SW renderer is not in use.
if (currentrenderer == 0)
mScene.ScreenResized();
}
void FSoftwareRenderer::SetClearColor(int color)

View file

@ -25,6 +25,7 @@ struct FSoftwareRenderer : public FRenderer
void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, double fov) override;
void SetColormap() override;
void Init() override;
private:
void PrecacheTexture(FTexture *tex, int cache);

View file

@ -108,7 +108,6 @@ EXTERN_CVAR(Bool, r_blendmethod)
int active_con_scale();
FRenderer *Renderer;
FRenderer *SWRenderer;
EXTERN_CVAR (Bool, swtruecolor)
@ -961,6 +960,10 @@ uint32_t DFrameBuffer::GetCaps()
return (uint32_t)FlagSet;
}
void DFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV)
{
SWRenderer->RenderTextureView(tex, Viewpoint, FOV);
}
CCMD(clean)
{

View file

@ -55,6 +55,7 @@ void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int real
class FTexture;
struct FColormap;
class FileWriter;
enum FTextureFormat : uint32_t;
// TagItem definitions for DrawTexture. As far as I know, tag lists
@ -357,6 +358,9 @@ public:
virtual void InitForLevel() {}
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 RenderView(player_t *player) {}
// Screen wiping
virtual bool WipeStartScreen(int type);

View file

@ -65,7 +65,6 @@ IVideo *Video;
// do not include GL headers here, only declare the necessary functions.
IVideo *gl_CreateVideo();
FRenderer *gl_CreateInterface();
void I_RestartRenderer();
int currentrenderer = -1;

View file

@ -20,7 +20,6 @@ EXTERN_CVAR(Int, vid_adapter);
extern IVideo *Video;
struct FRenderer;
FRenderer *gl_CreateInterface();