mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-25 21:41:03 +00:00
- changed shader loader to load only one shader at a time
This is merely preparation - the actual loading is still in one uninterrupted piece.
This commit is contained in:
parent
1452dd06a7
commit
2be13e1b9f
15 changed files with 197 additions and 86 deletions
|
@ -561,6 +561,11 @@ void OpenGLFrameBuffer::PostProcessScene(bool swscene, int fixedcm, float flash,
|
|||
GLRenderer->PostProcessScene(fixedcm, flash, afterBloomDrawEndScene2D);
|
||||
}
|
||||
|
||||
bool OpenGLFrameBuffer::CompileNextShader()
|
||||
{
|
||||
return GLRenderer->mShaderManager->CompileNextShader();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: WipeStartScreen
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
explicit OpenGLFrameBuffer() {}
|
||||
OpenGLFrameBuffer(void *hMonitor, bool fullscreen) ;
|
||||
~OpenGLFrameBuffer();
|
||||
|
||||
bool CompileNextShader() override;
|
||||
void InitializeState() override;
|
||||
void Update() override;
|
||||
|
||||
|
|
|
@ -672,7 +672,7 @@ bool FShader::Bind()
|
|||
FShader *FShaderCollection::Compile (const char *ShaderName, const char *ShaderPath, const char *LightModePath, const char *shaderdefines, bool usediscard, EPassType passType)
|
||||
{
|
||||
FString defines;
|
||||
defines += shaderdefines;
|
||||
if (shaderdefines) defines += shaderdefines;
|
||||
// this can't be in the shader code due to ATI strangeness.
|
||||
if (!usediscard) defines += "#define NO_ALPHATEST\n";
|
||||
if (passType == GBUFFER_PASS) defines += "#define GBUFFER_PASS\n";
|
||||
|
@ -707,6 +707,20 @@ FShaderManager::FShaderManager()
|
|||
mPassShaders.Push(new FShaderCollection((EPassType)passType));
|
||||
}
|
||||
|
||||
bool FShaderManager::CompileNextShader()
|
||||
{
|
||||
if (mPassShaders[mCompilePass]->CompileNextShader())
|
||||
{
|
||||
mCompilePass++;
|
||||
if (mCompilePass >= MAX_PASS_TYPES)
|
||||
{
|
||||
mCompilePass = -1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FShaderManager::~FShaderManager()
|
||||
{
|
||||
glUseProgram(0);
|
||||
|
@ -727,7 +741,7 @@ void FShaderManager::SetActiveShader(FShader *sh)
|
|||
|
||||
FShader *FShaderManager::BindEffect(int effect, EPassType passType)
|
||||
{
|
||||
if (passType < mPassShaders.Size())
|
||||
if (passType < mPassShaders.Size() && mCompilePass > -1)
|
||||
return mPassShaders[passType]->BindEffect(effect);
|
||||
else
|
||||
return nullptr;
|
||||
|
@ -735,7 +749,11 @@ FShader *FShaderManager::BindEffect(int effect, EPassType passType)
|
|||
|
||||
FShader *FShaderManager::Get(unsigned int eff, bool alphateston, EPassType passType)
|
||||
{
|
||||
if (r_skipmats && eff >= 3 && eff <= 4)
|
||||
if (mCompilePass > -1)
|
||||
{
|
||||
return mPassShaders[0]->Get(0, false);
|
||||
}
|
||||
if ((r_skipmats && eff >= 3 && eff <= 4))
|
||||
eff = 0;
|
||||
|
||||
if (passType < mPassShaders.Size())
|
||||
|
@ -752,7 +770,14 @@ FShader *FShaderManager::Get(unsigned int eff, bool alphateston, EPassType passT
|
|||
|
||||
FShaderCollection::FShaderCollection(EPassType passType)
|
||||
{
|
||||
CompileShaders(passType);
|
||||
mPassType = passType;
|
||||
mMaterialShaders.Clear();
|
||||
mMaterialShadersNAT.Clear();
|
||||
for (int i = 0; i < MAX_EFFECTS; i++)
|
||||
{
|
||||
mEffectShaders[i] = NULL;
|
||||
}
|
||||
CompileNextShader();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -772,35 +797,46 @@ FShaderCollection::~FShaderCollection()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderCollection::CompileShaders(EPassType passType)
|
||||
bool FShaderCollection::CompileNextShader()
|
||||
{
|
||||
mMaterialShaders.Clear();
|
||||
mMaterialShadersNAT.Clear();
|
||||
for (int i = 0; i < MAX_EFFECTS; i++)
|
||||
int i = mCompileIndex;
|
||||
if (mCompileState == 0)
|
||||
{
|
||||
mEffectShaders[i] = NULL;
|
||||
}
|
||||
|
||||
for(int i=0;defaultshaders[i].ShaderName != NULL;i++)
|
||||
{
|
||||
FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, defaultshaders[i].lightfunc, defaultshaders[i].Defines, true, passType);
|
||||
FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, defaultshaders[i].lightfunc, defaultshaders[i].Defines, true, mPassType);
|
||||
mMaterialShaders.Push(shc);
|
||||
if (i < SHADER_NoTexture)
|
||||
mCompileIndex++;
|
||||
if (defaultshaders[mCompileIndex].ShaderName == nullptr)
|
||||
{
|
||||
FShader *shc1 = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, defaultshaders[i].lightfunc, defaultshaders[i].Defines, false, passType);
|
||||
mMaterialShadersNAT.Push(shc1);
|
||||
mCompileIndex = 0;
|
||||
mCompileState++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned i = 0; i < usershaders.Size(); i++)
|
||||
else if (mCompileState == 1)
|
||||
{
|
||||
FShader *shc1 = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, defaultshaders[i].lightfunc, defaultshaders[i].Defines, false, mPassType);
|
||||
mMaterialShadersNAT.Push(shc1);
|
||||
mCompileIndex++;
|
||||
if (mCompileIndex >= SHADER_NoTexture)
|
||||
{
|
||||
mCompileIndex = 0;
|
||||
mCompileState++;
|
||||
if (usershaders.Size() == 0) mCompileState++;
|
||||
}
|
||||
}
|
||||
else if (mCompileState == 2)
|
||||
{
|
||||
FString name = ExtractFileBase(usershaders[i].shader);
|
||||
FString defines = defaultshaders[usershaders[i].shaderType].Defines + usershaders[i].defines;
|
||||
FShader *shc = Compile(name, usershaders[i].shader, defaultshaders[usershaders[i].shaderType].lightfunc, defines, true, passType);
|
||||
FShader *shc = Compile(name, usershaders[i].shader, defaultshaders[usershaders[i].shaderType].lightfunc, defines, true, mPassType);
|
||||
mMaterialShaders.Push(shc);
|
||||
if (mCompileIndex >= (int)usershaders.Size())
|
||||
{
|
||||
mCompileIndex = 0;
|
||||
mCompileState++;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0;i<MAX_EFFECTS;i++)
|
||||
else if (mCompileState == 3)
|
||||
{
|
||||
FShader *eff = new FShader(effectshaders[i].ShaderName);
|
||||
if (!eff->Load(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1,
|
||||
|
@ -809,7 +845,13 @@ void FShaderCollection::CompileShaders(EPassType passType)
|
|||
delete eff;
|
||||
}
|
||||
else mEffectShaders[i] = eff;
|
||||
mCompileIndex++;
|
||||
if (mCompileIndex >= MAX_EFFECTS)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -309,10 +309,12 @@ public:
|
|||
FShader *Get(unsigned int eff, bool alphateston, EPassType passType);
|
||||
|
||||
void SetActiveShader(FShader *sh);
|
||||
bool CompileNextShader();
|
||||
private:
|
||||
|
||||
FShader *mActiveShader = nullptr;
|
||||
TArray<FShaderCollection*> mPassShaders;
|
||||
int mCompilePass = 0;
|
||||
|
||||
friend class FShader;
|
||||
};
|
||||
|
@ -322,21 +324,23 @@ class FShaderCollection
|
|||
TArray<FShader*> mMaterialShaders;
|
||||
TArray<FShader*> mMaterialShadersNAT;
|
||||
FShader *mEffectShaders[MAX_EFFECTS];
|
||||
int mCompileState = 0, mCompileIndex = 0;
|
||||
EPassType mPassType;
|
||||
|
||||
void Clean();
|
||||
void CompileShaders(EPassType passType);
|
||||
|
||||
public:
|
||||
FShaderCollection(EPassType passType);
|
||||
~FShaderCollection();
|
||||
FShader *Compile(const char *ShaderName, const char *ShaderPath, const char *LightModePath, const char *shaderdefines, bool usediscard, EPassType passType);
|
||||
int Find(const char *mame);
|
||||
bool CompileNextShader();
|
||||
FShader *BindEffect(int effect);
|
||||
|
||||
FShader *Get(unsigned int eff, bool alphateston)
|
||||
{
|
||||
// indices 0-2 match the warping modes, 3 no texture, the following are custom
|
||||
if (!alphateston && eff <= 2)
|
||||
if (!alphateston && eff < SHADER_NoTexture)
|
||||
{
|
||||
return mMaterialShadersNAT[eff]; // Non-alphatest shaders are only created for default, warp1+2 and brightmap. The rest won't get used anyway
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ public:
|
|||
|
||||
void InitializeState() override;
|
||||
void Update() override;
|
||||
int GetShaderCount() override { return 0; }
|
||||
|
||||
void FirstEye() override;
|
||||
void NextEye(int eyecount) override;
|
||||
|
|
|
@ -733,7 +733,7 @@ bool FShader::Bind(ShaderFlavourData& flavour)
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// Since all shaders are REQUIRED, any error here needs to be fatal
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
@ -744,21 +744,8 @@ FShader *FShaderCollection::Compile (const char *ShaderName, const char *ShaderP
|
|||
// this can't be in the shader code due to ATI strangeness.
|
||||
if (!usediscard) defines += "#define NO_ALPHATEST\n";
|
||||
|
||||
FShader *shader = NULL;
|
||||
try
|
||||
{
|
||||
shader = new FShader(ShaderName);
|
||||
if (!shader->Configure(ShaderName, "shaders_gles/glsl/main.vp", "shaders_gles/glsl/main.fp", ShaderPath, LightModePath, defines.GetChars()))
|
||||
{
|
||||
I_FatalError("Unable to load shader %s\n", ShaderName);
|
||||
}
|
||||
}
|
||||
catch(CRecoverableError &err)
|
||||
{
|
||||
if (shader != NULL) delete shader;
|
||||
shader = NULL;
|
||||
I_FatalError("Unable to load shader %s:\n%s\n", ShaderName, err.GetMessage());
|
||||
}
|
||||
FShader *shader = new FShader(ShaderName);
|
||||
shader->Configure(ShaderName, "shaders_gles/glsl/main.vp", "shaders_gles/glsl/main.fp", ShaderPath, LightModePath, defines.GetChars());
|
||||
return shader;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,11 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "hw_shaderpatcher.h"
|
||||
#include "textures.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "v_video.h"
|
||||
|
||||
|
||||
static bool IsGlslWhitespace(char c)
|
||||
|
@ -296,3 +300,12 @@ const FEffectShader effectshaders[] =
|
|||
{ "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" },
|
||||
};
|
||||
|
||||
int DFrameBuffer::GetShaderCount()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; defaultshaders[i].ShaderName != nullptr; i++);
|
||||
|
||||
return MAX_PASS_TYPES * (countof(defaultshaders) - 1 + usershaders.Size() + MAX_EFFECTS + SHADER_NoTexture);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,3 +28,4 @@ struct FEffectShader
|
|||
|
||||
extern const FDefaultShader defaultshaders[];
|
||||
extern const FEffectShader effectshaders[];
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ public:
|
|||
|
||||
PolyFrameBuffer(void *hMonitor, bool fullscreen);
|
||||
~PolyFrameBuffer();
|
||||
int GetShaderCount() override { return 0; }
|
||||
|
||||
void Update() override;
|
||||
|
||||
|
|
|
@ -158,6 +158,8 @@ public:
|
|||
virtual void InitializeState() = 0; // For stuff that needs 'screen' set.
|
||||
virtual bool IsVulkan() { return false; }
|
||||
virtual bool IsPoly() { return false; }
|
||||
virtual int GetShaderCount();
|
||||
virtual bool CompileNextShader() { return true; }
|
||||
void SetAABBTree(hwrenderer::LevelAABBTree * tree)
|
||||
{
|
||||
mShadowMap.SetAABBTree(tree);
|
||||
|
|
|
@ -28,51 +28,93 @@
|
|||
#include "version.h"
|
||||
#include <ShaderLang.h>
|
||||
|
||||
bool VkShaderManager::CompileNextShader()
|
||||
{
|
||||
const char *mainvp = "shaders/glsl/main.vp";
|
||||
const char *mainfp = "shaders/glsl/main.fp";
|
||||
int i = compileIndex;
|
||||
|
||||
if (compileState == 0)
|
||||
{
|
||||
// regular material shaders
|
||||
|
||||
VkShaderProgram prog;
|
||||
prog.vert = LoadVertShader(defaultshaders[i].ShaderName, mainvp, defaultshaders[i].Defines);
|
||||
prog.frag = LoadFragShader(defaultshaders[i].ShaderName, mainfp, defaultshaders[i].gettexelfunc, defaultshaders[i].lightfunc, defaultshaders[i].Defines, true, compilePass == GBUFFER_PASS);
|
||||
mMaterialShaders[compilePass].push_back(std::move(prog));
|
||||
|
||||
compileIndex++;
|
||||
if (defaultshaders[compileIndex].ShaderName == nullptr)
|
||||
{
|
||||
compileIndex = 0;
|
||||
compileState++;
|
||||
}
|
||||
}
|
||||
else if (compileState == 1)
|
||||
{
|
||||
// NAT material shaders
|
||||
|
||||
VkShaderProgram natprog;
|
||||
natprog.vert = LoadVertShader(defaultshaders[i].ShaderName, mainvp, defaultshaders[i].Defines);
|
||||
natprog.frag = LoadFragShader(defaultshaders[i].ShaderName, mainfp, defaultshaders[i].gettexelfunc, defaultshaders[i].lightfunc, defaultshaders[i].Defines, false, compilePass == GBUFFER_PASS);
|
||||
mMaterialShadersNAT[compilePass].push_back(std::move(natprog));
|
||||
|
||||
compileIndex++;
|
||||
if (compileIndex == SHADER_NoTexture)
|
||||
{
|
||||
compileIndex = 0;
|
||||
compileState++;
|
||||
if (usershaders.Size() == 0) compileState++;
|
||||
}
|
||||
}
|
||||
else if (compileState == 2)
|
||||
{
|
||||
// user shaders
|
||||
|
||||
const FString& name = ExtractFileBase(usershaders[i].shader);
|
||||
FString defines = defaultshaders[usershaders[i].shaderType].Defines + usershaders[i].defines;
|
||||
|
||||
VkShaderProgram prog;
|
||||
prog.vert = LoadVertShader(name, mainvp, defines);
|
||||
prog.frag = LoadFragShader(name, mainfp, usershaders[i].shader, defaultshaders[usershaders[i].shaderType].lightfunc, defines, true, compilePass == GBUFFER_PASS);
|
||||
mMaterialShaders[compilePass].push_back(std::move(prog));
|
||||
|
||||
compileIndex++;
|
||||
if (compileIndex >= (int)usershaders.Size())
|
||||
{
|
||||
compileIndex = 0;
|
||||
compileState++;
|
||||
}
|
||||
}
|
||||
else if (compileState == 3)
|
||||
{
|
||||
// Effect shaders
|
||||
|
||||
VkShaderProgram prog;
|
||||
prog.vert = LoadVertShader(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].defines);
|
||||
prog.frag = LoadFragShader(effectshaders[i].ShaderName, effectshaders[i].fp1, effectshaders[i].fp2, effectshaders[i].fp3, effectshaders[i].defines, true, compilePass == GBUFFER_PASS);
|
||||
mEffectShaders[compilePass].push_back(std::move(prog));
|
||||
|
||||
compileIndex++;
|
||||
if (compileIndex >= MAX_EFFECTS)
|
||||
{
|
||||
compileIndex = 0;
|
||||
if (compilePass == MAX_PASS_TYPES)
|
||||
{
|
||||
compileIndex = -1; // we're done.
|
||||
return true;
|
||||
}
|
||||
compileState = 0;
|
||||
compilePass++;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
VkShaderManager::VkShaderManager(VulkanDevice *device) : device(device)
|
||||
{
|
||||
ShInitialize();
|
||||
|
||||
const char *mainvp = "shaders/glsl/main.vp";
|
||||
const char *mainfp = "shaders/glsl/main.fp";
|
||||
|
||||
for (int j = 0; j < MAX_PASS_TYPES; j++)
|
||||
{
|
||||
bool gbufferpass = j;
|
||||
for (int i = 0; defaultshaders[i].ShaderName != nullptr; i++)
|
||||
{
|
||||
VkShaderProgram prog;
|
||||
prog.vert = LoadVertShader(defaultshaders[i].ShaderName, mainvp, defaultshaders[i].Defines);
|
||||
prog.frag = LoadFragShader(defaultshaders[i].ShaderName, mainfp, defaultshaders[i].gettexelfunc, defaultshaders[i].lightfunc, defaultshaders[i].Defines, true, gbufferpass);
|
||||
mMaterialShaders[j].push_back(std::move(prog));
|
||||
|
||||
if (i < SHADER_NoTexture)
|
||||
{
|
||||
VkShaderProgram natprog;
|
||||
natprog.vert = LoadVertShader(defaultshaders[i].ShaderName, mainvp, defaultshaders[i].Defines);
|
||||
natprog.frag = LoadFragShader(defaultshaders[i].ShaderName, mainfp, defaultshaders[i].gettexelfunc, defaultshaders[i].lightfunc, defaultshaders[i].Defines, false, gbufferpass);
|
||||
mMaterialShadersNAT[j].push_back(std::move(natprog));
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < usershaders.Size(); i++)
|
||||
{
|
||||
FString name = ExtractFileBase(usershaders[i].shader);
|
||||
FString defines = defaultshaders[usershaders[i].shaderType].Defines + usershaders[i].defines;
|
||||
|
||||
VkShaderProgram prog;
|
||||
prog.vert = LoadVertShader(name, mainvp, defines);
|
||||
prog.frag = LoadFragShader(name, mainfp, usershaders[i].shader, defaultshaders[usershaders[i].shaderType].lightfunc, defines, true, gbufferpass);
|
||||
mMaterialShaders[j].push_back(std::move(prog));
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_EFFECTS; i++)
|
||||
{
|
||||
VkShaderProgram prog;
|
||||
prog.vert = LoadVertShader(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].defines);
|
||||
prog.frag = LoadFragShader(effectshaders[i].ShaderName, effectshaders[i].fp1, effectshaders[i].fp2, effectshaders[i].fp3, effectshaders[i].defines, true, gbufferpass);
|
||||
mEffectShaders[j].push_back(std::move(prog));
|
||||
}
|
||||
}
|
||||
CompileNextShader();
|
||||
}
|
||||
|
||||
VkShaderManager::~VkShaderManager()
|
||||
|
@ -82,7 +124,7 @@ VkShaderManager::~VkShaderManager()
|
|||
|
||||
VkShaderProgram *VkShaderManager::GetEffect(int effect, EPassType passType)
|
||||
{
|
||||
if (effect >= 0 && effect < MAX_EFFECTS && mEffectShaders[passType][effect].frag)
|
||||
if (compileIndex > -1 && effect >= 0 && effect < MAX_EFFECTS && mEffectShaders[passType][effect].frag)
|
||||
{
|
||||
return &mEffectShaders[passType][effect];
|
||||
}
|
||||
|
@ -91,8 +133,9 @@ VkShaderProgram *VkShaderManager::GetEffect(int effect, EPassType passType)
|
|||
|
||||
VkShaderProgram *VkShaderManager::Get(unsigned int eff, bool alphateston, EPassType passType)
|
||||
{
|
||||
if (compileIndex != -1) return &mMaterialShaders[0][0];
|
||||
// indices 0-2 match the warping modes, 3 no texture, the following are custom
|
||||
if (!alphateston && eff <= 2)
|
||||
if (!alphateston && eff <= SHADER_NoTexture)
|
||||
{
|
||||
return &mMaterialShadersNAT[passType][eff]; // Non-alphatest shaders are only created for default, warp1+2. The rest won't get used anyway
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ public:
|
|||
|
||||
VkShaderProgram *GetEffect(int effect, EPassType passType);
|
||||
VkShaderProgram *Get(unsigned int eff, bool alphateston, EPassType passType);
|
||||
bool CompileNextShader();
|
||||
|
||||
private:
|
||||
std::unique_ptr<VulkanShader> LoadVertShader(FString shadername, const char *vert_lump, const char *defines);
|
||||
|
@ -79,4 +80,6 @@ private:
|
|||
std::vector<VkShaderProgram> mMaterialShaders[MAX_PASS_TYPES];
|
||||
std::vector<VkShaderProgram> mMaterialShadersNAT[MAX_PASS_TYPES];
|
||||
std::vector<VkShaderProgram> mEffectShaders[MAX_PASS_TYPES];
|
||||
uint8_t compilePass = 0, compileState = 0;
|
||||
int compileIndex = 0;
|
||||
};
|
||||
|
|
|
@ -207,6 +207,11 @@ void VulkanFrameBuffer::Update()
|
|||
Super::Update();
|
||||
}
|
||||
|
||||
bool VulkanFrameBuffer::CompileNextShader()
|
||||
{
|
||||
return mShaderManager->CompileNextShader();
|
||||
}
|
||||
|
||||
void VulkanFrameBuffer::DeleteFrameObjects(bool uploadOnly)
|
||||
{
|
||||
FrameTextureUpload.Buffers.clear();
|
||||
|
|
|
@ -77,7 +77,7 @@ public:
|
|||
void Update() override;
|
||||
|
||||
void InitializeState() override;
|
||||
|
||||
bool CompileNextShader() override;
|
||||
void PrecacheMaterial(FMaterial *mat, int translation) override;
|
||||
void UpdatePalette() override;
|
||||
const char* DeviceName() const override;
|
||||
|
|
|
@ -3356,6 +3356,10 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
|
|||
}
|
||||
|
||||
V_Init2();
|
||||
while(!screen->CompileNextShader())
|
||||
{
|
||||
// here we can do some visual updates later
|
||||
}
|
||||
twod->fullscreenautoaspect = gameinfo.fullscreenautoaspect;
|
||||
// Initialize the size of the 2D drawer so that an attempt to access it outside the draw code won't crash.
|
||||
twod->Begin(screen->GetWidth(), screen->GetHeight());
|
||||
|
|
Loading…
Reference in a new issue